mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-11 15:28:00 +00:00
test(e2e): organise ingestion tests (#14649)
* test(e2e): organise ingestion tests * fix ingestion tests * push all the service ingestions * fix name regexp issue * fix database spec * aut fixes * fix follow entity tests * fix follow test case * fix soft delete tests * fix tests * fix dashboard * fix left side bar issue
This commit is contained in:
parent
65af782433
commit
ae884d54de
@ -29,9 +29,6 @@ export default defineConfig({
|
||||
setupNodeEvents(on, config) {
|
||||
return plugins(on, config);
|
||||
},
|
||||
specPattern: [
|
||||
'cypress/new-tests/**/*.spec.{js,jsx,ts,tsx}',
|
||||
'cypress/e2e/**/*.{js,jsx,ts,tsx}',
|
||||
],
|
||||
specPattern: ['cypress/e2e/**/*.{js,jsx,ts,tsx}'],
|
||||
},
|
||||
});
|
||||
|
||||
@ -35,6 +35,10 @@ class ContainerClass extends EntityClass {
|
||||
});
|
||||
}
|
||||
|
||||
followUnfollowEntity() {
|
||||
// Skiping this since not working from backend
|
||||
}
|
||||
|
||||
// Creation
|
||||
|
||||
createEntity() {
|
||||
|
||||
@ -50,6 +50,10 @@ class DatabaseClass extends EntityClass {
|
||||
verifyResponseStatusCode('@fetchDatabase', 200);
|
||||
}
|
||||
|
||||
followUnfollowEntity() {
|
||||
// Skiping this since not supported for database
|
||||
}
|
||||
|
||||
// Creation
|
||||
|
||||
createEntity() {
|
||||
|
||||
@ -62,6 +62,10 @@ class DatabaseSchemaClass extends EntityClass {
|
||||
verifyResponseStatusCode('@fetchDatabaseSchema', 200);
|
||||
}
|
||||
|
||||
followUnfollowEntity() {
|
||||
// Skiping this since not supported for database
|
||||
}
|
||||
|
||||
// Creation
|
||||
|
||||
createEntity() {
|
||||
|
||||
@ -32,10 +32,13 @@ import {
|
||||
createEntityViaREST,
|
||||
deleteEntity,
|
||||
deleteEntityViaREST,
|
||||
followEntity,
|
||||
hardDeleteEntity as hardDeleteEntityUtil,
|
||||
restoreEntity as restoreEntityUtil,
|
||||
unfollowEntity,
|
||||
updateDescriptioForEntity,
|
||||
updateDisplayNameForEntity,
|
||||
validateFollowedEntityToWidget,
|
||||
} from '../Utils/Entity';
|
||||
import {
|
||||
assignGlossaryTerm,
|
||||
@ -468,6 +471,14 @@ class EntityClass {
|
||||
deleteAnnoucement();
|
||||
}
|
||||
|
||||
followUnfollowEntity() {
|
||||
followEntity(this.endPoint);
|
||||
validateFollowedEntityToWidget(this.entityName, true);
|
||||
this.visitEntity();
|
||||
unfollowEntity(this.endPoint);
|
||||
validateFollowedEntityToWidget(this.entityName, false);
|
||||
}
|
||||
|
||||
// Custom property
|
||||
|
||||
setCustomProperty(propertydetails: CustomProperty, value: string) {
|
||||
|
||||
@ -35,6 +35,10 @@ class SearchIndexClass extends EntityClass {
|
||||
});
|
||||
}
|
||||
|
||||
followUnfollowEntity() {
|
||||
// Skiping this since not working from backend
|
||||
}
|
||||
|
||||
// Creation
|
||||
|
||||
createEntity() {
|
||||
|
||||
@ -0,0 +1,413 @@
|
||||
/*
|
||||
* 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 {
|
||||
INVALID_NAMES,
|
||||
NAME_VALIDATION_ERROR,
|
||||
} from '../../constants/constants';
|
||||
import {
|
||||
interceptURL,
|
||||
replaceAllSpacialCharWith_,
|
||||
toastNotification,
|
||||
verifyResponseStatusCode,
|
||||
} from '../common';
|
||||
import { visitEntityDetailsPage } from '../Utils/Entity';
|
||||
import {
|
||||
deleteService,
|
||||
getEntityTypeFromService,
|
||||
retryIngestionRun,
|
||||
Services,
|
||||
testConnection,
|
||||
} from '../Utils/Services';
|
||||
|
||||
const RETRIES_COUNT = 4;
|
||||
const RETRY_TIMES = 4;
|
||||
const BASE_WAIT_TIME = 20000;
|
||||
|
||||
export const descriptionBox =
|
||||
'.toastui-editor-md-container > .toastui-editor > .ProseMirror';
|
||||
|
||||
class ServiceBaseClass {
|
||||
public category: Services;
|
||||
protected serviceName: string;
|
||||
public serviceType: string;
|
||||
protected entityName: string;
|
||||
protected shouldTestConnection: boolean;
|
||||
protected shouldAddIngestion: boolean;
|
||||
|
||||
constructor(
|
||||
category: Services,
|
||||
name: string,
|
||||
serviceType: string,
|
||||
entity: string,
|
||||
shouldTestConnection = true,
|
||||
shouldAddIngestion = true
|
||||
) {
|
||||
this.category = category;
|
||||
this.serviceName = name;
|
||||
this.serviceType = serviceType;
|
||||
this.entityName = entity;
|
||||
this.shouldTestConnection = shouldTestConnection;
|
||||
this.shouldAddIngestion = shouldAddIngestion;
|
||||
}
|
||||
|
||||
visitService() {
|
||||
// Handle visit service here
|
||||
}
|
||||
|
||||
createService() {
|
||||
// Handle create service here
|
||||
// intercept the service requirement md file fetch request
|
||||
interceptURL(
|
||||
'GET',
|
||||
`en-US/*/${this.serviceType}.md`,
|
||||
'getServiceRequirements'
|
||||
);
|
||||
|
||||
cy.get('[data-testid="add-service-button"]').click();
|
||||
|
||||
// Select Service in step 1
|
||||
this.serviceSetp1(this.serviceType);
|
||||
|
||||
// Enter service name in step 2
|
||||
this.serviceSetp2(this.serviceName);
|
||||
|
||||
// Connection Details in step 3
|
||||
cy.get('[data-testid="add-new-service-container"]')
|
||||
.parent()
|
||||
.parent()
|
||||
.scrollTo('top', {
|
||||
ensureScrollable: false,
|
||||
});
|
||||
cy.contains('Connection Details').scrollIntoView().should('be.visible');
|
||||
|
||||
// Requirement panel should be visible and fetch the requirements md file
|
||||
cy.get('[data-testid="service-requirements"]').should('be.visible');
|
||||
verifyResponseStatusCode('@getServiceRequirements', [200, 304], {}, true);
|
||||
|
||||
this.fillConnectionDetails();
|
||||
|
||||
this.shouldTestConnection && testConnection();
|
||||
|
||||
this.submitService(this.serviceName);
|
||||
|
||||
this.shouldAddIngestion && this.addIngestionPipeline(this.serviceName);
|
||||
}
|
||||
|
||||
serviceSetp1(serviceType: string) {
|
||||
// Storing the created service name and the type of service
|
||||
// Select Service in step 1
|
||||
cy.get(`[data-testid="${serviceType}"]`).click();
|
||||
cy.get('[data-testid="next-button"]').click();
|
||||
}
|
||||
|
||||
serviceSetp2(serviceName: string) {
|
||||
// validation should work
|
||||
cy.get('[data-testid="next-button"]').click();
|
||||
|
||||
cy.get('#name_help').should('contain', 'Name is required');
|
||||
|
||||
// invalid name validation should work
|
||||
cy.get('[data-testid="service-name"]').type(
|
||||
INVALID_NAMES.WITH_SPECIAL_CHARS
|
||||
);
|
||||
cy.get('#name_help').should('contain', NAME_VALIDATION_ERROR);
|
||||
|
||||
cy.get('[data-testid="service-name"]').clear().type(serviceName);
|
||||
interceptURL('GET', '/api/v1/services/ingestionPipelines/ip', 'ipApi');
|
||||
interceptURL(
|
||||
'GET',
|
||||
'api/v1/services/ingestionPipelines/*',
|
||||
'ingestionPipelineStatus'
|
||||
);
|
||||
|
||||
cy.get('[data-testid="next-button"]').click();
|
||||
}
|
||||
|
||||
fillConnectionDetails() {
|
||||
// Handle fill connection details in respective service here
|
||||
}
|
||||
|
||||
fillIngestionDetails() {
|
||||
// Handle fill ingestion details in respective service here
|
||||
}
|
||||
|
||||
validateIngestionDetails() {
|
||||
// Handle validate ingestion details in respective service here
|
||||
}
|
||||
|
||||
addIngestionPipeline(serviceName: string) {
|
||||
cy.get('[data-testid="add-ingestion-button"]').click();
|
||||
|
||||
// Add ingestion page
|
||||
cy.get('[data-testid="add-ingestion-container"]').should('be.visible');
|
||||
|
||||
this.fillIngestionDetails();
|
||||
|
||||
cy.get('[data-testid="submit-btn"]').scrollIntoView().click();
|
||||
|
||||
// Go back and data should persist
|
||||
cy.get('[data-testid="back-button"]').scrollIntoView().click();
|
||||
|
||||
this.validateIngestionDetails();
|
||||
|
||||
// Go Next
|
||||
cy.get('[data-testid="submit-btn"]').scrollIntoView().click();
|
||||
|
||||
this.scheduleIngestion();
|
||||
|
||||
cy.contains(`${replaceAllSpacialCharWith_(serviceName)}_metadata`).should(
|
||||
'be.visible'
|
||||
);
|
||||
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/services/ingestionPipelines?*',
|
||||
'ingestionPipelines'
|
||||
);
|
||||
interceptURL('GET', '/api/v1/services/*/name/*', 'serviceDetails');
|
||||
|
||||
cy.get('[data-testid="view-service-button"]').click();
|
||||
verifyResponseStatusCode('@serviceDetails', 200);
|
||||
verifyResponseStatusCode('@ingestionPipelines', 200);
|
||||
this.handleIngestionRetry();
|
||||
}
|
||||
|
||||
submitService(serviceName: string) {
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/services/ingestionPipelines/status',
|
||||
'getIngestionPipelineStatus'
|
||||
);
|
||||
cy.get('[data-testid="submit-btn"]').should('exist').click();
|
||||
verifyResponseStatusCode('@getIngestionPipelineStatus', 200);
|
||||
|
||||
// check success
|
||||
cy.get('[data-testid="success-line"]').should('be.visible');
|
||||
cy.contains(`"${serviceName}"`).should('be.visible');
|
||||
cy.contains('has been created successfully').should('be.visible');
|
||||
}
|
||||
|
||||
scheduleIngestion(hasRetryCount = true) {
|
||||
interceptURL(
|
||||
'POST',
|
||||
'/api/v1/services/ingestionPipelines',
|
||||
'createIngestionPipelines'
|
||||
);
|
||||
interceptURL(
|
||||
'POST',
|
||||
'/api/v1/services/ingestionPipelines/deploy/*',
|
||||
'deployPipeline'
|
||||
);
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/services/ingestionPipelines/status',
|
||||
'getIngestionPipelineStatus'
|
||||
);
|
||||
// Schedule & Deploy
|
||||
cy.get('[data-testid="cron-type"]').should('be.visible').click();
|
||||
cy.get('.ant-select-item-option-content').contains('Hour').click();
|
||||
|
||||
if (hasRetryCount) {
|
||||
cy.get('#retries')
|
||||
.scrollIntoView()
|
||||
.clear()
|
||||
.type(RETRIES_COUNT + '');
|
||||
}
|
||||
|
||||
cy.get('[data-testid="deploy-button"]').click();
|
||||
|
||||
verifyResponseStatusCode('@createIngestionPipelines', 201);
|
||||
verifyResponseStatusCode('@deployPipeline', 200, {
|
||||
responseTimeout: 50000,
|
||||
});
|
||||
verifyResponseStatusCode('@getIngestionPipelineStatus', 200);
|
||||
// check success
|
||||
cy.get('[data-testid="success-line"]', { timeout: 15000 }).should(
|
||||
'be.visible'
|
||||
);
|
||||
cy.contains('has been created and deployed successfully').should(
|
||||
'be.visible'
|
||||
);
|
||||
}
|
||||
|
||||
handleIngestionRetry = (ingestionType = 'metadata') => {
|
||||
let timer = BASE_WAIT_TIME;
|
||||
const rowIndex = ingestionType === 'metadata' ? 1 : 2;
|
||||
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/services/ingestionPipelines?*',
|
||||
'ingestionPipelines'
|
||||
);
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/services/ingestionPipelines/*/pipelineStatus?startTs=*&endTs=*',
|
||||
'pipelineStatuses'
|
||||
);
|
||||
interceptURL('GET', '/api/v1/services/*/name/*', 'serviceDetails');
|
||||
interceptURL('GET', '/api/v1/permissions?limit=100', 'allPermissions');
|
||||
|
||||
// ingestions page
|
||||
let retryCount = 0;
|
||||
const testIngestionsTab = () => {
|
||||
// click on the tab only for the first time
|
||||
if (retryCount === 0) {
|
||||
cy.get('[data-testid="ingestions"]').should('exist').and('be.visible');
|
||||
cy.get('[data-testid="ingestions"] >> [data-testid="count"]').should(
|
||||
'have.text',
|
||||
rowIndex
|
||||
);
|
||||
cy.get('[data-testid="ingestions"]').click();
|
||||
|
||||
if (ingestionType === 'metadata') {
|
||||
verifyResponseStatusCode('@pipelineStatuses', 200, {
|
||||
responseTimeout: 50000,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
const checkSuccessState = () => {
|
||||
testIngestionsTab();
|
||||
|
||||
if (retryCount !== 0) {
|
||||
cy.wait('@allPermissions').then(() => {
|
||||
cy.wait('@serviceDetails').then(() => {
|
||||
verifyResponseStatusCode('@ingestionPipelines', 200);
|
||||
verifyResponseStatusCode('@pipelineStatuses', 200, {
|
||||
responseTimeout: 50000,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
retryCount++;
|
||||
|
||||
cy.get(`[data-row-key*="${ingestionType}"]`)
|
||||
.find('[data-testid="pipeline-status"]')
|
||||
.as('checkRun');
|
||||
// the latest run should be success
|
||||
cy.get('@checkRun').then(($ingestionStatus) => {
|
||||
const text = $ingestionStatus.text();
|
||||
if (
|
||||
text !== 'Success' &&
|
||||
text !== 'Failed' &&
|
||||
retryCount <= RETRY_TIMES
|
||||
) {
|
||||
// retry after waiting with log1 method [20s,40s,80s,160s,320s]
|
||||
cy.wait(timer);
|
||||
timer *= 2;
|
||||
cy.reload();
|
||||
checkSuccessState();
|
||||
} else {
|
||||
cy.get('@checkRun').should('contain', 'Success');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
checkSuccessState();
|
||||
};
|
||||
|
||||
updateService() {
|
||||
this.updateDescriptionForIngestedTables();
|
||||
}
|
||||
|
||||
updateDescriptionForIngestedTables() {
|
||||
const description = `${this.entityName} description`;
|
||||
interceptURL(
|
||||
'GET',
|
||||
`/api/v1/services/ingestionPipelines?fields=*&service=*`,
|
||||
'ingestionPipelines'
|
||||
);
|
||||
interceptURL('GET', `/api/v1/*?service=*&fields=*`, 'serviceDetails');
|
||||
interceptURL(
|
||||
'GET',
|
||||
`/api/v1/system/config/pipeline-service-client`,
|
||||
'pipelineServiceClient'
|
||||
);
|
||||
interceptURL(
|
||||
'GET',
|
||||
`/api/v1/services/ingestionPipelines/*/pipelineStatus?*`,
|
||||
'pipelineStatus'
|
||||
);
|
||||
// Navigate to ingested table
|
||||
visitEntityDetailsPage({
|
||||
term: this.entityName,
|
||||
serviceName: this.serviceName,
|
||||
entity: getEntityTypeFromService(this.category),
|
||||
});
|
||||
|
||||
// update description
|
||||
cy.get('[data-testid="edit-description"]').click();
|
||||
cy.get(descriptionBox).click().clear().type(description);
|
||||
interceptURL('PATCH', '/api/v1/*/*', 'updateEntity');
|
||||
cy.get('[data-testid="save"]').click();
|
||||
verifyResponseStatusCode('@updateEntity', 200);
|
||||
|
||||
// re-run ingestion flow
|
||||
cy.sidebarClick('app-bar-item-settings');
|
||||
|
||||
// Services page
|
||||
cy.get('.ant-menu-title-content').contains(this.category).click();
|
||||
interceptURL(
|
||||
'GET',
|
||||
'api/v1/search/query?q=*&from=0&size=15&index=*',
|
||||
'searchService'
|
||||
);
|
||||
cy.get('[data-testid="searchbar"]').type(this.serviceName);
|
||||
|
||||
verifyResponseStatusCode('@searchService', 200);
|
||||
|
||||
// click on created service
|
||||
cy.get(`[data-testid="service-name-${this.serviceName}"]`).click();
|
||||
|
||||
verifyResponseStatusCode('@serviceDetails', 200);
|
||||
verifyResponseStatusCode('@ingestionPipelines', 200);
|
||||
verifyResponseStatusCode('@pipelineServiceClient', 200);
|
||||
cy.get('[data-testid="ingestions"]').click();
|
||||
verifyResponseStatusCode('@pipelineStatus', 200);
|
||||
|
||||
interceptURL(
|
||||
'POST',
|
||||
'/api/v1/services/ingestionPipelines/trigger/*',
|
||||
'checkRun'
|
||||
);
|
||||
cy.get(
|
||||
`[data-row-key*="${replaceAllSpacialCharWith_(
|
||||
this.serviceName
|
||||
)}_metadata"] [data-testid="run"]`
|
||||
).click();
|
||||
verifyResponseStatusCode('@checkRun', 200);
|
||||
|
||||
toastNotification(`Pipeline triggered successfully!`);
|
||||
|
||||
// Wait for success
|
||||
retryIngestionRun();
|
||||
|
||||
// Navigate to table name
|
||||
visitEntityDetailsPage({
|
||||
term: this.entityName,
|
||||
serviceName: this.serviceName,
|
||||
entity: getEntityTypeFromService(this.category),
|
||||
});
|
||||
cy.get('[data-testid="markdown-parser"]')
|
||||
.first()
|
||||
.invoke('text')
|
||||
.should('contain', description);
|
||||
}
|
||||
|
||||
deleteService() {
|
||||
deleteService(this.category, this.serviceName);
|
||||
}
|
||||
}
|
||||
|
||||
export default ServiceBaseClass;
|
||||
@ -65,6 +65,10 @@ class StoreProcedureClass extends EntityClass {
|
||||
});
|
||||
}
|
||||
|
||||
followUnfollowEntity() {
|
||||
// Skiping this since not supported for store procedure
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
override cleanup() {
|
||||
super.cleanup();
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 ServiceBaseClass from '../Entities/ServiceBaseClass';
|
||||
import { Services } from '../Utils/Services';
|
||||
|
||||
class MetabaseIngestionClass extends ServiceBaseClass {
|
||||
name: string;
|
||||
serviceName: string;
|
||||
serviceType: string;
|
||||
|
||||
constructor() {
|
||||
super(Services.Pipeline, 'cypress-Airflow', 'Airflow', 'index_metadata');
|
||||
}
|
||||
|
||||
createService() {
|
||||
super.createService();
|
||||
}
|
||||
|
||||
updateService() {
|
||||
// Backend issue for udpating displayName
|
||||
}
|
||||
|
||||
fillConnectionDetails() {
|
||||
cy.get('#root\\/hostPort').type(Cypress.env('airflowHostPort'));
|
||||
cy.get('#root\\/connection__oneof_select')
|
||||
.scrollIntoView()
|
||||
.select('BackendConnection');
|
||||
}
|
||||
|
||||
deleteService() {
|
||||
super.deleteService();
|
||||
}
|
||||
}
|
||||
|
||||
export default MetabaseIngestionClass;
|
||||
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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 { checkServiceFieldSectionHighlighting } from '../common';
|
||||
import ServiceBaseClass from '../Entities/ServiceBaseClass';
|
||||
import { Services } from '../Utils/Services';
|
||||
|
||||
class MetabaseIngestionClass extends ServiceBaseClass {
|
||||
name: string;
|
||||
filterPattern;
|
||||
|
||||
constructor() {
|
||||
super(Services.Database, 'cypress-BigQuery', 'BigQuery', 'testtable');
|
||||
|
||||
this.filterPattern = 'testschema';
|
||||
}
|
||||
|
||||
createService() {
|
||||
super.createService();
|
||||
}
|
||||
|
||||
updateService() {
|
||||
// super.updateService();
|
||||
// Issue with searching ingested data
|
||||
}
|
||||
|
||||
fillConnectionDetails() {
|
||||
const clientEmail = Cypress.env('bigqueryClientEmail');
|
||||
cy.get('.form-group > #root\\/credentials\\/gcpConfig\\/type')
|
||||
.scrollIntoView()
|
||||
.type('service_account');
|
||||
checkServiceFieldSectionHighlighting('type');
|
||||
cy.get('#root\\/credentials\\/gcpConfig\\/projectId')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('bigqueryProjectId'));
|
||||
checkServiceFieldSectionHighlighting('projectId');
|
||||
cy.get('#root\\/credentials\\/gcpConfig\\/privateKeyId')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('bigqueryPrivateKeyId'));
|
||||
checkServiceFieldSectionHighlighting('privateKeyId');
|
||||
cy.get('#root\\/credentials\\/gcpConfig\\/privateKey')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('bigqueryPrivateKey'));
|
||||
checkServiceFieldSectionHighlighting('privateKey');
|
||||
cy.get('#root\\/credentials\\/gcpConfig\\/clientEmail')
|
||||
.scrollIntoView()
|
||||
.type(clientEmail);
|
||||
checkServiceFieldSectionHighlighting('clientEmail');
|
||||
cy.get('#root\\/credentials\\/gcpConfig\\/clientId')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('bigqueryClientId'));
|
||||
checkServiceFieldSectionHighlighting('clientId');
|
||||
cy.get('#root\\/credentials\\/gcpConfig\\/clientX509CertUrl')
|
||||
.scrollIntoView()
|
||||
.type(
|
||||
`https://www.googleapis.com/robot/v1/metadata/x509/${encodeURIComponent(
|
||||
clientEmail
|
||||
)}`
|
||||
);
|
||||
checkServiceFieldSectionHighlighting('clientX509CertUrl');
|
||||
cy.get('[data-testid="add-item-Taxonomy Project IDs"]')
|
||||
.scrollIntoView()
|
||||
.click();
|
||||
checkServiceFieldSectionHighlighting('taxonomyProjectID');
|
||||
cy.get('#root\\/taxonomyProjectID\\/0')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('bigqueryProjectIdTaxonomy'));
|
||||
checkServiceFieldSectionHighlighting('taxonomyProjectID');
|
||||
}
|
||||
|
||||
fillIngestionDetails() {
|
||||
cy.get('#root\\/schemaFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
.type(`${this.filterPattern}{enter}`);
|
||||
}
|
||||
|
||||
deleteService() {
|
||||
super.deleteService();
|
||||
}
|
||||
}
|
||||
|
||||
export default MetabaseIngestionClass;
|
||||
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 { checkServiceFieldSectionHighlighting } from '../common';
|
||||
import ServiceBaseClass from '../Entities/ServiceBaseClass';
|
||||
import { Services } from '../Utils/Services';
|
||||
|
||||
class KafkaIngestionClass extends ServiceBaseClass {
|
||||
constructor() {
|
||||
super(Services.Messaging, 'cypress-Kafka', 'Kafka', '__transaction_state');
|
||||
}
|
||||
|
||||
createService() {
|
||||
super.createService();
|
||||
}
|
||||
|
||||
updateService() {
|
||||
super.updateService();
|
||||
}
|
||||
|
||||
fillConnectionDetails() {
|
||||
cy.get('#root\\/bootstrapServers').type(
|
||||
Cypress.env('kafkaBootstrapServers')
|
||||
);
|
||||
checkServiceFieldSectionHighlighting('bootstrapServers');
|
||||
cy.get('#root\\/schemaRegistryURL').type(
|
||||
Cypress.env('kafkaSchemaRegistryUrl')
|
||||
);
|
||||
checkServiceFieldSectionHighlighting('schemaRegistryURL');
|
||||
}
|
||||
|
||||
fillIngestionDetails() {
|
||||
cy.get('#root\\/topicFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
.type(`${this.entityName}{enter}`);
|
||||
}
|
||||
|
||||
deleteService() {
|
||||
super.deleteService();
|
||||
}
|
||||
}
|
||||
|
||||
export default KafkaIngestionClass;
|
||||
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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 { checkServiceFieldSectionHighlighting } from '../common';
|
||||
import ServiceBaseClass from '../Entities/ServiceBaseClass';
|
||||
import { Services } from '../Utils/Services';
|
||||
|
||||
class MetabaseIngestionClass extends ServiceBaseClass {
|
||||
name: string;
|
||||
tableName = 'jaffle_shop dashboard';
|
||||
constructor() {
|
||||
super(
|
||||
Services.Dashboard,
|
||||
'cypress-Metabase',
|
||||
'Metabase',
|
||||
'jaffle_shop dashboard'
|
||||
);
|
||||
this.tableName = 'jaffle_shop dashboard';
|
||||
}
|
||||
|
||||
createService() {
|
||||
super.createService();
|
||||
}
|
||||
|
||||
updateService() {
|
||||
// Backend issue for searching with displayName
|
||||
// super.updateService();
|
||||
}
|
||||
|
||||
fillConnectionDetails() {
|
||||
cy.get('#root\\/username')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('metabaseUsername'));
|
||||
checkServiceFieldSectionHighlighting('username');
|
||||
cy.get('#root\\/password')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('metabasePassword'));
|
||||
checkServiceFieldSectionHighlighting('password');
|
||||
cy.get('#root\\/hostPort')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('metabaseHostPort'));
|
||||
checkServiceFieldSectionHighlighting('hostPort');
|
||||
}
|
||||
|
||||
fillIngestionDetails() {
|
||||
cy.get('#root\\/dashboardFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
.type(`${this.tableName}{enter}`);
|
||||
}
|
||||
|
||||
deleteService() {
|
||||
super.deleteService();
|
||||
}
|
||||
}
|
||||
|
||||
export default MetabaseIngestionClass;
|
||||
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 { checkServiceFieldSectionHighlighting } from '../common';
|
||||
import ServiceBaseClass from '../Entities/ServiceBaseClass';
|
||||
import { Services } from '../Utils/Services';
|
||||
|
||||
class MlFlowIngestionClass extends ServiceBaseClass {
|
||||
constructor() {
|
||||
super(
|
||||
Services.MLModels,
|
||||
'cypress-Ml-Model',
|
||||
'Mlflow',
|
||||
'ElasticnetWineModel',
|
||||
false,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
createService() {
|
||||
super.createService();
|
||||
}
|
||||
|
||||
updateService() {
|
||||
// Do nothing here
|
||||
}
|
||||
|
||||
fillConnectionDetails() {
|
||||
cy.get('#root\\/trackingUri').type('mlModelTrackingUri');
|
||||
checkServiceFieldSectionHighlighting('trackingUri');
|
||||
cy.get('#root\\/registryUri').type('mlModelRegistryUri');
|
||||
checkServiceFieldSectionHighlighting('registryUri');
|
||||
}
|
||||
|
||||
fillIngestionDetails() {
|
||||
cy.get('#root\\/mlModelFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
.type(`${this.entityName}{enter}`);
|
||||
}
|
||||
|
||||
deleteService() {
|
||||
super.deleteService();
|
||||
}
|
||||
}
|
||||
|
||||
export default MlFlowIngestionClass;
|
||||
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 { checkServiceFieldSectionHighlighting } from '../common';
|
||||
import ServiceBaseClass from '../Entities/ServiceBaseClass';
|
||||
import { Services } from '../Utils/Services';
|
||||
|
||||
class MysqlIngestionClass extends ServiceBaseClass {
|
||||
name: string;
|
||||
tableFilter: string;
|
||||
constructor() {
|
||||
super(Services.Database, 'cypress-mysql', 'Mysql', 'bot_entity');
|
||||
this.tableFilter = 'bot_entity{enter} alert_entity{enter} chart_entity';
|
||||
}
|
||||
|
||||
createService() {
|
||||
super.createService();
|
||||
}
|
||||
|
||||
fillConnectionDetails() {
|
||||
cy.get('#root\\/username').type(Cypress.env('mysqlUsername'));
|
||||
checkServiceFieldSectionHighlighting('username');
|
||||
cy.get('#root\\/authType\\/password').type(Cypress.env('mysqlPassword'));
|
||||
checkServiceFieldSectionHighlighting('password');
|
||||
cy.get('#root\\/hostPort').type(Cypress.env('mysqlHostPort'));
|
||||
checkServiceFieldSectionHighlighting('hostPort');
|
||||
}
|
||||
|
||||
fillIngestionDetails() {
|
||||
cy.get('#root\\/tableFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
.type(this.tableFilter);
|
||||
}
|
||||
|
||||
validateIngestionDetails() {
|
||||
const tables = this.tableFilter.replace(/{enter} /g, '');
|
||||
cy.get('.ant-select-selection-item-content')
|
||||
.then((content) => content.text())
|
||||
.should('deep.eq', tables);
|
||||
}
|
||||
}
|
||||
|
||||
export default MysqlIngestionClass;
|
||||
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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 { checkServiceFieldSectionHighlighting } from '../common';
|
||||
import ServiceBaseClass from '../Entities/ServiceBaseClass';
|
||||
import { Services } from '../Utils/Services';
|
||||
|
||||
class S3IngestionClass extends ServiceBaseClass {
|
||||
name: string;
|
||||
constructor() {
|
||||
super(Services.Storage, 'cypress-s3-storage', 'S3', 'cypress-bucket');
|
||||
}
|
||||
|
||||
createService() {
|
||||
super.createService();
|
||||
}
|
||||
|
||||
updateService() {
|
||||
super.updateService();
|
||||
}
|
||||
|
||||
fillConnectionDetails() {
|
||||
cy.get('#root\\/awsConfig\\/awsAccessKeyId').type(
|
||||
Cypress.env('s3StorageAccessKeyId')
|
||||
);
|
||||
checkServiceFieldSectionHighlighting('awsAccessKeyId');
|
||||
cy.get('#root\\/awsConfig\\/awsSecretAccessKey').type(
|
||||
Cypress.env('s3StorageSecretAccessKey')
|
||||
);
|
||||
checkServiceFieldSectionHighlighting('awsSecretAccessKey');
|
||||
cy.get('#root\\/awsConfig\\/awsRegion').type('us');
|
||||
checkServiceFieldSectionHighlighting('awsRegion');
|
||||
cy.get('#root\\/awsConfig\\/endPointURL').type(
|
||||
Cypress.env('s3StorageEndPointUrl')
|
||||
);
|
||||
checkServiceFieldSectionHighlighting('endPointURL');
|
||||
}
|
||||
}
|
||||
|
||||
export default S3IngestionClass;
|
||||
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 { checkServiceFieldSectionHighlighting } from '../common';
|
||||
import ServiceBaseClass from '../Entities/ServiceBaseClass';
|
||||
import { Services } from '../Utils/Services';
|
||||
|
||||
class SnowflakeIngestionClass extends ServiceBaseClass {
|
||||
schema: string;
|
||||
constructor() {
|
||||
super(Services.Database, 'cypress-Snowflake', 'Snowflake', 'CUSTOMER');
|
||||
this.schema = 'TPCH_SF1000';
|
||||
}
|
||||
|
||||
createService() {
|
||||
super.createService();
|
||||
}
|
||||
|
||||
fillConnectionDetails() {
|
||||
cy.get('#root\\/username').type(Cypress.env('snowflakeUsername'));
|
||||
checkServiceFieldSectionHighlighting('username');
|
||||
cy.get('#root\\/password').type(Cypress.env('snowflakePassword'));
|
||||
checkServiceFieldSectionHighlighting('password');
|
||||
cy.get('#root\\/account').type(Cypress.env('snowflakeAccount'));
|
||||
checkServiceFieldSectionHighlighting('account');
|
||||
cy.get('#root\\/database').type(Cypress.env('snowflakeDatabase'));
|
||||
checkServiceFieldSectionHighlighting('database');
|
||||
cy.get('#root\\/warehouse').type(Cypress.env('snowflakeWarehouse'));
|
||||
checkServiceFieldSectionHighlighting('warehouse');
|
||||
}
|
||||
|
||||
fillIngestionDetails() {
|
||||
cy.get('#root\\/schemaFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
.type(`${this.schema}{enter}`);
|
||||
}
|
||||
|
||||
deleteService() {
|
||||
super.deleteService();
|
||||
}
|
||||
}
|
||||
|
||||
export default SnowflakeIngestionClass;
|
||||
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 ServiceBaseClass from '../Entities/ServiceBaseClass';
|
||||
import { Services } from '../Utils/Services';
|
||||
|
||||
class SupersetIngestionClass extends ServiceBaseClass {
|
||||
constructor() {
|
||||
super(
|
||||
Services.Dashboard,
|
||||
'cypress-Superset',
|
||||
'Superset',
|
||||
"World Bank's Data"
|
||||
);
|
||||
}
|
||||
|
||||
createService() {
|
||||
super.createService();
|
||||
}
|
||||
|
||||
updateService() {
|
||||
// Issue with searching ingested data
|
||||
}
|
||||
|
||||
fillConnectionDetails() {
|
||||
cy.get('#root\\/connection\\/username')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('supersetUsername'));
|
||||
cy.get('#root\\/connection\\/password')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('supersetPassword'));
|
||||
cy.get('#root\\/hostPort')
|
||||
.scrollIntoView()
|
||||
.focus()
|
||||
.clear()
|
||||
.type(Cypress.env('supersetHostPort'));
|
||||
}
|
||||
|
||||
fillIngestionDetails() {
|
||||
cy.get('#root\\/dashboardFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
.type(`${this.entityName}{enter}`);
|
||||
}
|
||||
|
||||
deleteService() {
|
||||
super.deleteService();
|
||||
}
|
||||
}
|
||||
|
||||
export default SupersetIngestionClass;
|
||||
@ -14,7 +14,6 @@ import { DELETE_TERM } from '../../constants/constants';
|
||||
import {
|
||||
EntityType,
|
||||
EXPLORE_PAGE_TABS,
|
||||
SEARCH_INDEX,
|
||||
} from '../../constants/Entity.interface';
|
||||
import {
|
||||
ENTITIES_WITHOUT_FOLLOWING_BUTTON,
|
||||
@ -177,11 +176,6 @@ export const visitEntityDetailsPage = ({
|
||||
interceptURL('GET', '/api/v1/*/name/*', 'getEntityDetails');
|
||||
}
|
||||
|
||||
interceptURL(
|
||||
'GET',
|
||||
`/api/v1/search/query?q=**&index=${SEARCH_INDEX[entity]}&from=*&size=**`,
|
||||
'explorePageTabSearch'
|
||||
);
|
||||
interceptURL(
|
||||
'GET',
|
||||
`/api/v1/search/query?q=**&from=*&size=*&index=all`,
|
||||
@ -221,9 +215,9 @@ export const visitEntityDetailsPage = ({
|
||||
|
||||
cy.get(`[data-testid="${tabName}-tab"]`).click();
|
||||
|
||||
verifyResponseStatusCode('@explorePageTabSearch', 200);
|
||||
|
||||
cy.get(`[data-testid="${id}"] [data-testid="entity-link"]`)
|
||||
cy.get(`[data-testid="${id}"] [data-testid="entity-link"]`, {
|
||||
timeout: 10000,
|
||||
})
|
||||
.scrollIntoView()
|
||||
.click();
|
||||
}
|
||||
@ -441,7 +435,11 @@ export const deleteEntity = (entityName: string, endPoint: EntityType) => {
|
||||
toastNotification('deleted successfully!');
|
||||
|
||||
cy.reload();
|
||||
cy.get('[data-testid="deleted-badge"]').should('have.text', 'Deleted');
|
||||
|
||||
cy.get('[data-testid="deleted-badge"]', { timeout: 10000 }).should(
|
||||
'have.text',
|
||||
'Deleted'
|
||||
);
|
||||
|
||||
deletedEntityCommonChecks({ entityType: endPoint, deleted: true });
|
||||
|
||||
@ -471,8 +469,7 @@ export const deleteEntity = (entityName: string, endPoint: EntityType) => {
|
||||
'1'
|
||||
);
|
||||
|
||||
cy.get('.ant-table-row > :nth-child(1)').should('contain', entityName);
|
||||
cy.get('.ant-table-row > :nth-child(1)').contains(entityName).click();
|
||||
cy.get(`[data-testid=${entityName}]`).click();
|
||||
}
|
||||
|
||||
restoreEntity();
|
||||
@ -555,3 +552,36 @@ export const updateDescriptioForEntity = (
|
||||
'[data-testid="asset-description-container"] [data-testid="viewer-container"]'
|
||||
).should('contain', description);
|
||||
};
|
||||
|
||||
export const followEntity = (entityType: EntityType) => {
|
||||
interceptURL('PUT', `/api/v1/${entityType}/*/followers`, 'waitAfterFollow');
|
||||
|
||||
cy.get('[data-testid="entity-follow-button"]').scrollIntoView().click();
|
||||
|
||||
verifyResponseStatusCode('@waitAfterFollow', 200);
|
||||
};
|
||||
|
||||
export const validateFollowedEntityToWidget = (
|
||||
entityName: string,
|
||||
isFollowed = true
|
||||
) => {
|
||||
interceptURL('GET', '/api/v1/users/*?fields=follows*', 'getFollowedEntities');
|
||||
cy.goToHomePage();
|
||||
|
||||
verifyResponseStatusCode('@getFollowedEntities', 200, { timeout: 10000 });
|
||||
cy.get(`[data-testid="following-${entityName}"]`).should(
|
||||
isFollowed ? 'be.visible' : 'not.exist'
|
||||
);
|
||||
};
|
||||
|
||||
export const unfollowEntity = (entityType: EntityType) => {
|
||||
interceptURL(
|
||||
'DELETE',
|
||||
`/api/v1/${entityType}/*/followers/*`,
|
||||
'waitAfterUnFollow'
|
||||
);
|
||||
|
||||
cy.get('[data-testid="entity-follow-button"]').scrollIntoView().click();
|
||||
|
||||
verifyResponseStatusCode('@waitAfterUnFollow', 200);
|
||||
};
|
||||
|
||||
@ -10,7 +10,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { EntityType } from '../../new-tests/base/EntityClass';
|
||||
|
||||
import { EntityType } from '../../constants/Entity.interface';
|
||||
import { interceptURL, verifyResponseStatusCode } from '../common';
|
||||
|
||||
export const assignGlossaryTerm = (
|
||||
|
||||
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* 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 { DELETE_TERM } from '../../constants/constants';
|
||||
import { EntityType } from '../../constants/Entity.interface';
|
||||
import {
|
||||
interceptURL,
|
||||
toastNotification,
|
||||
verifyResponseStatusCode,
|
||||
} from '../common';
|
||||
|
||||
export enum Services {
|
||||
Database = 'Databases',
|
||||
Messaging = 'Messaging',
|
||||
Dashboard = 'Dashboards',
|
||||
Pipeline = 'Pipelines',
|
||||
MLModels = 'ML Models',
|
||||
Storage = 'Storages',
|
||||
Search = 'Search',
|
||||
}
|
||||
|
||||
export const RETRY_TIMES = 4;
|
||||
export const BASE_WAIT_TIME = 20000;
|
||||
|
||||
export const goToServiceListingPage = (services: Services) => {
|
||||
interceptURL(
|
||||
'GET',
|
||||
'api/v1/teams/name/Organization?fields=*',
|
||||
'getSettingsPage'
|
||||
);
|
||||
// Click on settings page
|
||||
cy.sidebarClick('app-bar-item-settings');
|
||||
verifyResponseStatusCode('@getSettingsPage', 200);
|
||||
// Services page
|
||||
interceptURL('GET', '/api/v1/services/*', 'getServiceList');
|
||||
cy.get(`[data-testid="global-setting-left-panel"]`)
|
||||
.contains(services)
|
||||
.click();
|
||||
|
||||
verifyResponseStatusCode('@getServiceList', 200);
|
||||
};
|
||||
|
||||
export const getEntityTypeFromService = (service: Services) => {
|
||||
switch (service) {
|
||||
case Services.Dashboard:
|
||||
return EntityType.DashboardService;
|
||||
case Services.Database:
|
||||
return EntityType.DatabaseService;
|
||||
case Services.Storage:
|
||||
return EntityType.StorageService;
|
||||
case Services.Messaging:
|
||||
return EntityType.MessagingService;
|
||||
case Services.Search:
|
||||
return EntityType.SearchService;
|
||||
case Services.MLModels:
|
||||
return EntityType.MlModelService;
|
||||
case Services.Pipeline:
|
||||
return EntityType.PipelineService;
|
||||
default:
|
||||
return EntityType.DatabaseService;
|
||||
}
|
||||
};
|
||||
|
||||
export const retryIngestionRun = () => {
|
||||
interceptURL('GET', '/api/v1/services/*/name/*', 'serviceDetails');
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/services/ingestionPipelines/*/pipelineStatus/*',
|
||||
'pipelineStatus'
|
||||
);
|
||||
let timer = BASE_WAIT_TIME;
|
||||
let retryCount = 0;
|
||||
const testIngestionsTab = () => {
|
||||
cy.get('[data-testid="ingestions"]').scrollIntoView().should('be.visible');
|
||||
cy.get('[data-testid="ingestions"] >> [data-testid="count"]').should(
|
||||
'have.text',
|
||||
'1'
|
||||
);
|
||||
if (retryCount === 0) {
|
||||
cy.wait(1000);
|
||||
cy.get('[data-testid="ingestions"]').should('be.visible');
|
||||
}
|
||||
};
|
||||
|
||||
const checkSuccessState = () => {
|
||||
testIngestionsTab();
|
||||
retryCount++;
|
||||
|
||||
// the latest run should be success
|
||||
cy.get('[data-testid="pipeline-status"]').then(($ingestionStatus) => {
|
||||
if ($ingestionStatus.text() !== 'Success' && retryCount <= RETRY_TIMES) {
|
||||
// retry after waiting with log1 method [20s,40s,80s,160s,320s]
|
||||
cy.wait(timer);
|
||||
timer *= 2;
|
||||
cy.reload();
|
||||
verifyResponseStatusCode('@serviceDetails', 200);
|
||||
verifyResponseStatusCode('@pipelineStatus', 200);
|
||||
checkSuccessState();
|
||||
} else {
|
||||
cy.get('[data-testid="pipeline-status"]').should('contain', 'Success');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
checkSuccessState();
|
||||
};
|
||||
|
||||
export const deleteService = (typeOfService: Services, serviceName: string) => {
|
||||
interceptURL(
|
||||
'GET',
|
||||
'api/v1/search/query?q=*&from=0&size=15&index=*',
|
||||
'searchService'
|
||||
);
|
||||
cy.get('[data-testid="searchbar"]').type(serviceName);
|
||||
|
||||
verifyResponseStatusCode('@searchService', 200);
|
||||
|
||||
// click on created service
|
||||
cy.get(`[data-testid="service-name-${serviceName}"]`).click();
|
||||
|
||||
cy.get(`[data-testid="entity-header-display-name"]`)
|
||||
.invoke('text')
|
||||
.then((text) => {
|
||||
expect(text).to.equal(serviceName);
|
||||
});
|
||||
|
||||
// Clicking on permanent delete radio button and checking the service name
|
||||
cy.get('[data-testid="manage-button"]').click();
|
||||
|
||||
cy.get('[data-menu-id*="delete-button"]').should('be.visible');
|
||||
cy.get('[data-testid="delete-button-title"]').click();
|
||||
|
||||
// Clicking on permanent delete radio button and checking the service name
|
||||
cy.get('[data-testid="hard-delete-option"]').contains(serviceName).click();
|
||||
|
||||
cy.get('[data-testid="confirmation-text-input"]').type(DELETE_TERM);
|
||||
interceptURL(
|
||||
'DELETE',
|
||||
`/api/v1/${getEntityTypeFromService(typeOfService)}/*`,
|
||||
'deleteService'
|
||||
);
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/services/*/name/*?fields=owner',
|
||||
'serviceDetails'
|
||||
);
|
||||
|
||||
cy.get('[data-testid="confirm-button"]').click();
|
||||
verifyResponseStatusCode('@deleteService', 200);
|
||||
|
||||
// Closing the toast notification
|
||||
toastNotification(`Service deleted successfully!`);
|
||||
|
||||
cy.get(`[data-testid="service-name-${serviceName}"]`).should('not.exist');
|
||||
};
|
||||
|
||||
export const testConnection = () => {
|
||||
// Test the connection
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/services/testConnectionDefinitions/name/*',
|
||||
'testConnectionStepDefinition'
|
||||
);
|
||||
|
||||
interceptURL('POST', '/api/v1/automations/workflows', 'createWorkflow');
|
||||
|
||||
interceptURL(
|
||||
'POST',
|
||||
'/api/v1/automations/workflows/trigger/*',
|
||||
'triggerWorkflow'
|
||||
);
|
||||
|
||||
interceptURL('GET', '/api/v1/automations/workflows/*', 'getWorkflow');
|
||||
|
||||
cy.get('[data-testid="test-connection-btn"]').should('exist').click();
|
||||
|
||||
verifyResponseStatusCode('@testConnectionStepDefinition', 200);
|
||||
|
||||
verifyResponseStatusCode('@createWorkflow', 201);
|
||||
// added extra buffer time as triggerWorkflow API can take up to 2minute to provide result
|
||||
verifyResponseStatusCode('@triggerWorkflow', 200, {
|
||||
responseTimeout: 120000,
|
||||
});
|
||||
cy.get('[data-testid="test-connection-modal"]').should('exist');
|
||||
cy.get('.ant-modal-footer > .ant-btn-primary')
|
||||
.should('exist')
|
||||
.contains('OK')
|
||||
.click();
|
||||
verifyResponseStatusCode('@getWorkflow', 200);
|
||||
cy.get('[data-testid="messag-text"]').then(($message) => {
|
||||
if ($message.text().includes('partially successful')) {
|
||||
cy.contains('Test connection partially successful').should('exist');
|
||||
} else {
|
||||
cy.contains('Connection test was successful').should('exist');
|
||||
}
|
||||
});
|
||||
};
|
||||
@ -24,16 +24,9 @@ export const searchServiceFromSettingPage = (service) => {
|
||||
};
|
||||
|
||||
export const visitServiceDetailsPage = (service, verifyHeader = true) => {
|
||||
// Click on settings page
|
||||
interceptURL(
|
||||
'GET',
|
||||
'api/v1/teams/name/Organization?fields=*',
|
||||
'getSettingsPage'
|
||||
);
|
||||
|
||||
cy.sidebarClick('app-bar-item-settings');
|
||||
|
||||
verifyResponseStatusCode('@getSettingsPage', 200);
|
||||
// Services page
|
||||
interceptURL('GET', '/api/v1/services/*', 'getServices');
|
||||
|
||||
|
||||
@ -29,6 +29,7 @@ export enum EntityType {
|
||||
PipelineService = 'services/pipelineServices',
|
||||
MessagingService = 'services/messagingServices',
|
||||
SearchService = 'services/searchServices',
|
||||
MetadataService = 'services/metadataServices',
|
||||
Database = 'databases',
|
||||
DatabaseSchema = 'databaseSchemas',
|
||||
DataModel = 'dashboard/datamodels',
|
||||
@ -48,6 +49,7 @@ export const EXPLORE_PAGE_TABS: Record<
|
||||
| EntityType.DatabaseSchema
|
||||
| EntityType.GlossaryTerm
|
||||
| EntityType.Domain
|
||||
| EntityType.MetadataService
|
||||
>,
|
||||
string
|
||||
> = {
|
||||
@ -76,6 +78,7 @@ export const SEARCH_INDEX: Record<
|
||||
| EntityType.Database
|
||||
| EntityType.DatabaseSchema
|
||||
| EntityType.GlossaryTerm
|
||||
| EntityType.MetadataService
|
||||
>,
|
||||
string
|
||||
> = {
|
||||
|
||||
@ -77,7 +77,6 @@ describe('Activity feed', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.get("[data-testid='welcome-screen-close-btn']").click();
|
||||
});
|
||||
|
||||
it('Create feed', () => {
|
||||
|
||||
@ -1,208 +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,
|
||||
visitEntityDetailsPage,
|
||||
} from '../../common/common';
|
||||
import {
|
||||
createEntityTable,
|
||||
createSingleLevelEntity,
|
||||
hardDeleteService,
|
||||
} from '../../common/EntityUtils';
|
||||
import {
|
||||
DASHBOARD_DATA_MODEL_DETAILS,
|
||||
DATABASE_SERVICE,
|
||||
SINGLE_LEVEL_SERVICE,
|
||||
STORED_PROCEDURE_DETAILS,
|
||||
VISIT_ENTITIES_DATA,
|
||||
} from '../../constants/EntityConstant';
|
||||
import { SERVICE_CATEGORIES } from '../../constants/service.constants';
|
||||
|
||||
// eslint-disable-next-line spaced-comment
|
||||
/// <reference types="cypress" />
|
||||
|
||||
// Update list if we support this for other entities too
|
||||
const FOLLOWING_ENTITIES = [
|
||||
VISIT_ENTITIES_DATA.table,
|
||||
VISIT_ENTITIES_DATA.dashboard,
|
||||
VISIT_ENTITIES_DATA.topic,
|
||||
VISIT_ENTITIES_DATA.pipeline,
|
||||
VISIT_ENTITIES_DATA.mlmodel,
|
||||
VISIT_ENTITIES_DATA.storedProcedure,
|
||||
VISIT_ENTITIES_DATA.dataModel,
|
||||
];
|
||||
|
||||
const followEntity = ({ term, serviceName, entity }, isUnfollow) => {
|
||||
visitEntityDetailsPage({ term, serviceName, entity });
|
||||
|
||||
if (entity === 'dashboardDataModel') {
|
||||
interceptURL(
|
||||
isUnfollow ? 'DELETE' : 'PUT',
|
||||
isUnfollow
|
||||
? '/api/v1/dashboard/datamodels/*/followers/*'
|
||||
: '/api/v1/dashboard/datamodels/*/followers',
|
||||
'waitAfterFollow'
|
||||
);
|
||||
} else {
|
||||
interceptURL(
|
||||
isUnfollow ? 'DELETE' : 'PUT',
|
||||
isUnfollow ? '/api/v1/*/*/followers/*' : '/api/v1/*/*/followers',
|
||||
'waitAfterFollow'
|
||||
);
|
||||
}
|
||||
|
||||
interceptURL(
|
||||
isUnfollow ? 'DELETE' : 'PUT',
|
||||
isUnfollow ? '/api/v1/*/*/followers/*' : '/api/v1/*/*/followers',
|
||||
'waitAfterFollow'
|
||||
);
|
||||
cy.get('[data-testid="entity-follow-button"]')
|
||||
.scrollIntoView()
|
||||
.should('be.visible')
|
||||
.click();
|
||||
|
||||
verifyResponseStatusCode('@waitAfterFollow', 200);
|
||||
};
|
||||
|
||||
describe('Following data assets', () => {
|
||||
before(() => {
|
||||
cy.login();
|
||||
cy.getAllLocalStorage().then((data) => {
|
||||
const token = Object.values(data)[0].oidcIdToken;
|
||||
|
||||
createEntityTable({
|
||||
token,
|
||||
...DATABASE_SERVICE,
|
||||
tables: [DATABASE_SERVICE.entity],
|
||||
});
|
||||
SINGLE_LEVEL_SERVICE.forEach((data) => {
|
||||
createSingleLevelEntity({
|
||||
token,
|
||||
...data,
|
||||
entity: [data.entity],
|
||||
});
|
||||
});
|
||||
|
||||
// creating data model
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: `/api/v1/dashboard/datamodels`,
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
body: DASHBOARD_DATA_MODEL_DETAILS,
|
||||
});
|
||||
// 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 = Object.values(data)[0].oidcIdToken;
|
||||
|
||||
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();
|
||||
cy.get("[data-testid='welcome-screen-close-btn']").click();
|
||||
});
|
||||
|
||||
it('following section should be present', () => {
|
||||
cy.get('[data-testid="following-widget"]')
|
||||
.scrollIntoView()
|
||||
.should('be.visible');
|
||||
|
||||
cy.get('[data-testid="following-widget"]').contains(
|
||||
'You have not followed anything yet.'
|
||||
);
|
||||
cy.get(`[data-testid="following-widget"] .right-panel-list-item`).should(
|
||||
'have.length',
|
||||
0
|
||||
);
|
||||
});
|
||||
|
||||
// Follow entity
|
||||
FOLLOWING_ENTITIES.map((entity, index) => {
|
||||
it(`following section should have ${entity.term} followed`, () => {
|
||||
followEntity(entity);
|
||||
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/feed?type=Announcement&activeAnnouncement=true',
|
||||
'getAnnoucemenets'
|
||||
);
|
||||
|
||||
cy.clickOnLogo();
|
||||
verifyResponseStatusCode('@getAnnoucemenets', 200);
|
||||
|
||||
if (index < 5) {
|
||||
cy.get(`[data-testid="following-${entity.displayName}"]`).should(
|
||||
'be.visible'
|
||||
);
|
||||
}
|
||||
|
||||
// Checking count of following
|
||||
cy.get(`[data-testid="following-data"]`).should('contain', index + 1);
|
||||
});
|
||||
});
|
||||
|
||||
// UnFollow entity
|
||||
FOLLOWING_ENTITIES.map((entity, index) => {
|
||||
it(`unfollowing entity ${entity.term} should removed from following section`, () => {
|
||||
followEntity(entity, true);
|
||||
|
||||
interceptURL(
|
||||
'GET',
|
||||
'/api/v1/feed?type=Announcement&activeAnnouncement=true',
|
||||
'getAnnoucemenets'
|
||||
);
|
||||
|
||||
cy.clickOnLogo();
|
||||
verifyResponseStatusCode('@getAnnoucemenets', 200);
|
||||
|
||||
cy.get(`[data-testid="following-${entity.displayName}"]`).should(
|
||||
'not.exist'
|
||||
);
|
||||
|
||||
if (index === FOLLOWING_ENTITIES.length - 1) {
|
||||
// Checking count of following
|
||||
cy.get(`[data-testid="following-data"]`).should('not.exist');
|
||||
} else {
|
||||
// Checking count of following
|
||||
cy.get(`[data-testid="following-data"]`).should(
|
||||
'contain',
|
||||
FOLLOWING_ENTITIES.length - (index + 1)
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -82,7 +82,6 @@ describe('Query Entity', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.get("[data-testid='welcome-screen-close-btn']").click();
|
||||
});
|
||||
|
||||
it('Create query', () => {
|
||||
|
||||
@ -92,7 +92,6 @@ describe('Recently viwed data assets', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.get("[data-testid='welcome-screen-close-btn']").click();
|
||||
});
|
||||
|
||||
it('recently view section should be present', () => {
|
||||
|
||||
@ -102,6 +102,10 @@ entities.forEach((entity) => {
|
||||
entity.downVote();
|
||||
});
|
||||
|
||||
it(`follow unfollow entity`, () => {
|
||||
entity.followUnfollowEntity();
|
||||
});
|
||||
|
||||
Object.values(CustomPropertyType).forEach((type) => {
|
||||
it(`Set ${type} Custom Property `, () => {
|
||||
entity.setCustomProperty(
|
||||
|
||||
@ -130,7 +130,11 @@ entities.forEach((entity) => {
|
||||
});
|
||||
}
|
||||
|
||||
it(`Update displayName`, () => {
|
||||
it(`follow unfollow entity`, () => {
|
||||
entity.followUnfollowEntity();
|
||||
});
|
||||
|
||||
it.skip(`Update displayName`, () => {
|
||||
entity.renameEntity();
|
||||
});
|
||||
|
||||
|
||||
@ -1,75 +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.
|
||||
*/
|
||||
// eslint-disable-next-line spaced-comment
|
||||
/// <reference types="cypress" />
|
||||
|
||||
import {
|
||||
deleteCreatedService,
|
||||
goToAddNewServicePage,
|
||||
testServiceCreationAndIngestion,
|
||||
updateDescriptionForIngestedTables,
|
||||
uuid,
|
||||
} from '../../common/common';
|
||||
import {
|
||||
API_SERVICE,
|
||||
DATA_ASSETS,
|
||||
SERVICE_TYPE,
|
||||
} from '../../constants/constants';
|
||||
|
||||
const serviceType = 'Airflow';
|
||||
const serviceName = `${serviceType}-ct-test-${uuid()}`;
|
||||
const tableName = 'index_metadata';
|
||||
const description = `This is ${tableName} description`;
|
||||
|
||||
const connectionInput = () => {
|
||||
cy.get('#root\\/hostPort').type(Cypress.env('airflowHostPort'));
|
||||
cy.get('#root\\/connection__oneof_select')
|
||||
.scrollIntoView()
|
||||
.select('BackendConnection');
|
||||
};
|
||||
|
||||
describe('Airflow Ingestion', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('add and ingest data', () => {
|
||||
goToAddNewServicePage(SERVICE_TYPE.Pipeline);
|
||||
|
||||
testServiceCreationAndIngestion({
|
||||
serviceType,
|
||||
connectionInput,
|
||||
serviceName,
|
||||
type: SERVICE_TYPE.Pipeline,
|
||||
serviceCategory: SERVICE_TYPE.Pipeline,
|
||||
});
|
||||
});
|
||||
|
||||
it.skip('Update pipeline description and verify description after re-run', () => {
|
||||
updateDescriptionForIngestedTables(
|
||||
serviceName,
|
||||
tableName,
|
||||
description,
|
||||
SERVICE_TYPE.Pipeline,
|
||||
DATA_ASSETS.pipelines
|
||||
);
|
||||
});
|
||||
|
||||
it('delete created service', () => {
|
||||
deleteCreatedService(
|
||||
SERVICE_TYPE.Pipeline,
|
||||
serviceName,
|
||||
API_SERVICE.pipelineServices
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1,67 +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 {
|
||||
checkServiceFieldSectionHighlighting,
|
||||
deleteCreatedService,
|
||||
goToAddNewServicePage,
|
||||
testServiceCreationAndIngestion,
|
||||
uuid,
|
||||
} from '../../common/common';
|
||||
import { API_SERVICE, SERVICE_TYPE } from '../../constants/constants';
|
||||
|
||||
const serviceType = 'Mlflow';
|
||||
const serviceName = `${serviceType}-ct-test-${uuid()}`;
|
||||
const modelName = 'ElasticnetWineModel';
|
||||
|
||||
const connectionInput = () => {
|
||||
cy.get('#root\\/trackingUri').type('mlModelTrackingUri');
|
||||
checkServiceFieldSectionHighlighting('trackingUri');
|
||||
cy.get('#root\\/registryUri').type('mlModelRegistryUri');
|
||||
checkServiceFieldSectionHighlighting('registryUri');
|
||||
};
|
||||
|
||||
const addIngestionInput = () => {
|
||||
cy.get('#root\\/mlModelFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
.type(`${modelName}{enter}`);
|
||||
};
|
||||
|
||||
describe('ML Flow Ingestion', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('add and ingest data', () => {
|
||||
goToAddNewServicePage(SERVICE_TYPE.MLModels);
|
||||
|
||||
testServiceCreationAndIngestion({
|
||||
serviceType,
|
||||
connectionInput,
|
||||
addIngestionInput,
|
||||
serviceName,
|
||||
type: SERVICE_TYPE.MLModels,
|
||||
serviceCategory: 'MlModel',
|
||||
shouldAddIngestion: false,
|
||||
allowTestConnection: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('delete created service', () => {
|
||||
deleteCreatedService(
|
||||
SERVICE_TYPE.MLModels,
|
||||
serviceName,
|
||||
API_SERVICE.mlmodelServices,
|
||||
'Mlmodel'
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1,84 +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 {
|
||||
checkServiceFieldSectionHighlighting,
|
||||
deleteCreatedService,
|
||||
goToAddNewServicePage,
|
||||
testServiceCreationAndIngestion,
|
||||
updateDescriptionForIngestedTables,
|
||||
uuid,
|
||||
} from '../../common/common';
|
||||
import {
|
||||
API_SERVICE,
|
||||
DATA_ASSETS,
|
||||
SERVICE_TYPE,
|
||||
} from '../../constants/constants';
|
||||
|
||||
const serviceType = 'S3';
|
||||
const serviceName = `${serviceType}-ct-test-${uuid()}`;
|
||||
const tableName = 'cypress-bucket';
|
||||
const description = `This is ${tableName} description`;
|
||||
|
||||
const connectionInput = () => {
|
||||
cy.get('#root\\/awsConfig\\/awsAccessKeyId').type(
|
||||
Cypress.env('s3StorageAccessKeyId')
|
||||
);
|
||||
checkServiceFieldSectionHighlighting('awsAccessKeyId');
|
||||
cy.get('#root\\/awsConfig\\/awsSecretAccessKey').type(
|
||||
Cypress.env('s3StorageSecretAccessKey')
|
||||
);
|
||||
checkServiceFieldSectionHighlighting('awsSecretAccessKey');
|
||||
cy.get('#root\\/awsConfig\\/awsRegion').type('us');
|
||||
checkServiceFieldSectionHighlighting('awsRegion');
|
||||
cy.get('#root\\/awsConfig\\/endPointURL').type(
|
||||
Cypress.env('s3StorageEndPointUrl')
|
||||
);
|
||||
checkServiceFieldSectionHighlighting('endPointURL');
|
||||
};
|
||||
|
||||
describe('S3Storage Ingestion', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('add and ingest data', () => {
|
||||
goToAddNewServicePage(SERVICE_TYPE.Storage);
|
||||
|
||||
testServiceCreationAndIngestion({
|
||||
serviceType,
|
||||
connectionInput,
|
||||
serviceName,
|
||||
type: SERVICE_TYPE.Storage,
|
||||
serviceCategory: SERVICE_TYPE.Storage,
|
||||
});
|
||||
});
|
||||
|
||||
it('Update container description and verify description after re-run', () => {
|
||||
updateDescriptionForIngestedTables(
|
||||
serviceName,
|
||||
tableName,
|
||||
description,
|
||||
SERVICE_TYPE.Storage,
|
||||
DATA_ASSETS.containers
|
||||
);
|
||||
});
|
||||
|
||||
// Todo: unskip below test once issue is fixed https://github.com/open-metadata/OpenMetadata/issues/11700
|
||||
it.skip('delete created service', () => {
|
||||
deleteCreatedService(
|
||||
SERVICE_TYPE.Storage,
|
||||
serviceName,
|
||||
API_SERVICE.storageServices
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 AirflowIngestionClass from '../../common/Services/AirflowIngestionClass';
|
||||
import BigQueryIngestionClass from '../../common/Services/BigQueryIngestionClass';
|
||||
import KafkaIngestionClass from '../../common/Services/KafkaIngestionClass';
|
||||
import MetabaseIngestionClass from '../../common/Services/MetabaseIngestionClass';
|
||||
import MlFlowIngestionClass from '../../common/Services/MlFlowIngestionClass';
|
||||
import MysqlIngestionClass from '../../common/Services/MysqlIngestionClass';
|
||||
import S3IngestionClass from '../../common/Services/S3IngestionClass';
|
||||
import SnowflakeIngestionClass from '../../common/Services/SnowflakeIngestionClass';
|
||||
import SupersetIngestionClass from '../../common/Services/SupersetIngestionClass';
|
||||
import { goToServiceListingPage } from '../../common/Utils/Services';
|
||||
|
||||
const services = [
|
||||
new S3IngestionClass(),
|
||||
new MetabaseIngestionClass(),
|
||||
new MysqlIngestionClass(),
|
||||
new AirflowIngestionClass(),
|
||||
new BigQueryIngestionClass(),
|
||||
new KafkaIngestionClass(),
|
||||
new MlFlowIngestionClass(),
|
||||
new SnowflakeIngestionClass(),
|
||||
new SupersetIngestionClass(),
|
||||
];
|
||||
|
||||
services.forEach((service) => {
|
||||
describe(`${service.serviceType} Ingestion`, () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
goToServiceListingPage(service.category);
|
||||
});
|
||||
|
||||
it(`Create & Ingest ${service.serviceType} service`, () => {
|
||||
service.createService();
|
||||
});
|
||||
|
||||
it(`Update description and verify description after re-run`, () => {
|
||||
service.updateService();
|
||||
});
|
||||
|
||||
it(`Delete ${service.serviceType} service`, () => {
|
||||
service.deleteService();
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 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 {
|
||||
checkServiceFieldSectionHighlighting,
|
||||
deleteCreatedService,
|
||||
goToAddNewServicePage,
|
||||
testServiceCreationAndIngestion,
|
||||
updateDescriptionForIngestedTables,
|
||||
uuid,
|
||||
} from '../../common/common';
|
||||
import { API_SERVICE, SERVICE_TYPE } from '../../constants/constants';
|
||||
|
||||
const serviceType = 'BigQuery';
|
||||
const serviceName = `${serviceType}-ct-test-${uuid()}`;
|
||||
const tableName = 'testtable';
|
||||
const description = `This is ${serviceName} description`;
|
||||
const filterPattern = 'testschema';
|
||||
|
||||
describe('BigQuery Ingestion', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('add and ingest data', () => {
|
||||
goToAddNewServicePage(SERVICE_TYPE.Database);
|
||||
const connectionInput = () => {
|
||||
const clientEmail = Cypress.env('bigqueryClientEmail');
|
||||
cy.get('.form-group > #root\\/credentials\\/gcpConfig\\/type')
|
||||
.scrollIntoView()
|
||||
.type('service_account');
|
||||
checkServiceFieldSectionHighlighting('type');
|
||||
cy.get('#root\\/credentials\\/gcpConfig\\/projectId')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('bigqueryProjectId'));
|
||||
checkServiceFieldSectionHighlighting('projectId');
|
||||
cy.get('#root\\/credentials\\/gcpConfig\\/privateKeyId')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('bigqueryPrivateKeyId'));
|
||||
checkServiceFieldSectionHighlighting('privateKeyId');
|
||||
cy.get('#root\\/credentials\\/gcpConfig\\/privateKey')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('bigqueryPrivateKey'));
|
||||
checkServiceFieldSectionHighlighting('privateKey');
|
||||
cy.get('#root\\/credentials\\/gcpConfig\\/clientEmail')
|
||||
.scrollIntoView()
|
||||
.type(clientEmail);
|
||||
checkServiceFieldSectionHighlighting('clientEmail');
|
||||
cy.get('#root\\/credentials\\/gcpConfig\\/clientId')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('bigqueryClientId'));
|
||||
checkServiceFieldSectionHighlighting('clientId');
|
||||
cy.get('#root\\/credentials\\/gcpConfig\\/clientX509CertUrl')
|
||||
.scrollIntoView()
|
||||
.type(
|
||||
`https://www.googleapis.com/robot/v1/metadata/x509/${encodeURIComponent(
|
||||
clientEmail
|
||||
)}`
|
||||
);
|
||||
checkServiceFieldSectionHighlighting('clientX509CertUrl');
|
||||
cy.get('[data-testid="add-item-Taxonomy Project IDs"]')
|
||||
.scrollIntoView()
|
||||
.click();
|
||||
checkServiceFieldSectionHighlighting('taxonomyProjectID');
|
||||
cy.get('#root\\/taxonomyProjectID\\/0')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('bigqueryProjectIdTaxonomy'));
|
||||
checkServiceFieldSectionHighlighting('taxonomyProjectID');
|
||||
};
|
||||
|
||||
const addIngestionInput = () => {
|
||||
cy.get('#root\\/schemaFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
.type(`${filterPattern}{enter}`);
|
||||
};
|
||||
|
||||
testServiceCreationAndIngestion({
|
||||
serviceType,
|
||||
connectionInput,
|
||||
addIngestionInput,
|
||||
serviceName,
|
||||
serviceCategory: SERVICE_TYPE.Database,
|
||||
});
|
||||
});
|
||||
|
||||
it('Update table description and verify description after re-run', () => {
|
||||
updateDescriptionForIngestedTables(
|
||||
serviceName,
|
||||
tableName,
|
||||
description,
|
||||
SERVICE_TYPE.Database,
|
||||
'tables'
|
||||
);
|
||||
});
|
||||
|
||||
it('delete created service', () => {
|
||||
deleteCreatedService(
|
||||
SERVICE_TYPE.Database,
|
||||
serviceName,
|
||||
API_SERVICE.databaseServices
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 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 {
|
||||
checkServiceFieldSectionHighlighting,
|
||||
deleteCreatedService,
|
||||
goToAddNewServicePage,
|
||||
testServiceCreationAndIngestion,
|
||||
updateDescriptionForIngestedTables,
|
||||
uuid,
|
||||
} from '../../common/common';
|
||||
import { API_SERVICE, SERVICE_TYPE } from '../../constants/constants';
|
||||
|
||||
const serviceType = 'Glue';
|
||||
const serviceName = `${serviceType}-ct-test-${uuid()}`;
|
||||
const tableName = 'cloudfront_logs2';
|
||||
const description = `This is ${serviceName} description`;
|
||||
const filterPattern = 'default';
|
||||
|
||||
// We do not have creds for glue to validate
|
||||
describe.skip('Glue Ingestion', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('add and ingest data', () => {
|
||||
goToAddNewServicePage(SERVICE_TYPE.Database);
|
||||
const connectionInput = () => {
|
||||
cy.get('#root\\/awsConfig\\/awsAccessKeyId')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('glueAwsAccessKeyId'));
|
||||
checkServiceFieldSectionHighlighting('awsAccessKeyId');
|
||||
cy.get('#root\\/awsConfig\\/awsSecretAccessKey')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('glueAwsSecretAccessKey'));
|
||||
checkServiceFieldSectionHighlighting('awsSecretAccessKey');
|
||||
cy.get('#root\\/awsConfig\\/awsRegion')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('glueAwsRegion'));
|
||||
checkServiceFieldSectionHighlighting('awsRegion');
|
||||
cy.get('#root\\/awsConfig\\/endPointURL')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('glueEndPointURL'));
|
||||
checkServiceFieldSectionHighlighting('endPointURL');
|
||||
};
|
||||
|
||||
const addIngestionInput = () => {
|
||||
cy.get('#root\\/schemaFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
.type(`${filterPattern}{enter}`);
|
||||
};
|
||||
|
||||
testServiceCreationAndIngestion({
|
||||
serviceType,
|
||||
connectionInput,
|
||||
addIngestionInput,
|
||||
serviceName,
|
||||
testIngestionButton: false,
|
||||
serviceCategory: SERVICE_TYPE.Database,
|
||||
});
|
||||
});
|
||||
|
||||
it('Update table description and verify description after re-run', () => {
|
||||
updateDescriptionForIngestedTables(
|
||||
serviceName,
|
||||
tableName,
|
||||
description,
|
||||
SERVICE_TYPE.Database,
|
||||
'tables'
|
||||
);
|
||||
});
|
||||
|
||||
it('delete created service', () => {
|
||||
deleteCreatedService(
|
||||
SERVICE_TYPE.Database,
|
||||
serviceName,
|
||||
API_SERVICE.databaseServices
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 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 {
|
||||
checkServiceFieldSectionHighlighting,
|
||||
deleteCreatedService,
|
||||
goToAddNewServicePage,
|
||||
testServiceCreationAndIngestion,
|
||||
updateDescriptionForIngestedTables,
|
||||
uuid,
|
||||
} from '../../common/common';
|
||||
import { API_SERVICE, SERVICE_TYPE } from '../../constants/constants';
|
||||
|
||||
const serviceType = 'Kafka';
|
||||
const serviceName = `${serviceType}-ct-test-${uuid()}`;
|
||||
const topicName = '__transaction_state';
|
||||
const description = `This is ${serviceName} description`;
|
||||
|
||||
describe('Kafka Ingestion', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('add and ingest data', () => {
|
||||
goToAddNewServicePage(SERVICE_TYPE.Messaging);
|
||||
|
||||
// Select Dashboard services
|
||||
cy.get('[data-testid="service-category"]').should('be.visible').click();
|
||||
cy.get('.ant-select-item-option-content')
|
||||
.contains('Messaging Services')
|
||||
.click();
|
||||
|
||||
const connectionInput = () => {
|
||||
cy.get('#root\\/bootstrapServers').type(
|
||||
Cypress.env('kafkaBootstrapServers')
|
||||
);
|
||||
checkServiceFieldSectionHighlighting('bootstrapServers');
|
||||
cy.get('#root\\/schemaRegistryURL').type(
|
||||
Cypress.env('kafkaSchemaRegistryUrl')
|
||||
);
|
||||
checkServiceFieldSectionHighlighting('schemaRegistryURL');
|
||||
};
|
||||
|
||||
const addIngestionInput = () => {
|
||||
cy.get('#root\\/topicFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
|
||||
.type(`${topicName}{enter}`);
|
||||
};
|
||||
|
||||
testServiceCreationAndIngestion({
|
||||
serviceType: 'Kafka',
|
||||
connectionInput,
|
||||
addIngestionInput,
|
||||
serviceName,
|
||||
type: 'messaging',
|
||||
serviceCategory: SERVICE_TYPE.Messaging,
|
||||
});
|
||||
});
|
||||
|
||||
it('Update table description and verify description after re-run', () => {
|
||||
updateDescriptionForIngestedTables(
|
||||
serviceName,
|
||||
topicName,
|
||||
description,
|
||||
SERVICE_TYPE.Messaging,
|
||||
'topics'
|
||||
);
|
||||
});
|
||||
|
||||
it('delete created service', () => {
|
||||
deleteCreatedService(
|
||||
SERVICE_TYPE.Messaging,
|
||||
serviceName,
|
||||
API_SERVICE.messagingServices
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 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 {
|
||||
checkServiceFieldSectionHighlighting,
|
||||
deleteCreatedService,
|
||||
goToAddNewServicePage,
|
||||
testServiceCreationAndIngestion,
|
||||
updateDescriptionForIngestedTables,
|
||||
uuid,
|
||||
} from '../../common/common';
|
||||
import { API_SERVICE, SERVICE_TYPE } from '../../constants/constants';
|
||||
|
||||
const serviceType = 'Metabase';
|
||||
const serviceName = `${serviceType}-ct-test-${uuid()}`;
|
||||
const tableName = 'jaffle_shop dashboard';
|
||||
const description = `This is ${serviceName} description`;
|
||||
|
||||
describe('Metabase Ingestion', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('add and ingest data', () => {
|
||||
goToAddNewServicePage(SERVICE_TYPE.Dashboard);
|
||||
|
||||
// Select Dashboard services
|
||||
cy.get('[data-testid="service-category"]').should('be.visible').click();
|
||||
cy.get('.ant-select-item-option-content')
|
||||
.contains('Dashboard Services')
|
||||
.click();
|
||||
|
||||
const connectionInput = () => {
|
||||
cy.get('#root\\/username')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('metabaseUsername'));
|
||||
checkServiceFieldSectionHighlighting('username');
|
||||
cy.get('#root\\/password')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('metabasePassword'));
|
||||
checkServiceFieldSectionHighlighting('password');
|
||||
cy.get('#root\\/hostPort')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('metabaseHostPort'));
|
||||
checkServiceFieldSectionHighlighting('hostPort');
|
||||
};
|
||||
|
||||
const addIngestionInput = () => {
|
||||
cy.get('#root\\/dashboardFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
|
||||
.type(`${tableName}{enter}`);
|
||||
};
|
||||
|
||||
testServiceCreationAndIngestion({
|
||||
serviceType,
|
||||
connectionInput,
|
||||
addIngestionInput,
|
||||
serviceName,
|
||||
type: 'dashboard',
|
||||
serviceCategory: SERVICE_TYPE.Dashboard,
|
||||
});
|
||||
});
|
||||
|
||||
it.skip('Update table description and verify description after re-run', () => {
|
||||
updateDescriptionForIngestedTables(
|
||||
serviceName,
|
||||
tableName,
|
||||
description,
|
||||
SERVICE_TYPE.Dashboard,
|
||||
'dashboards'
|
||||
);
|
||||
});
|
||||
|
||||
it('delete created service', () => {
|
||||
deleteCreatedService(
|
||||
SERVICE_TYPE.Dashboard,
|
||||
serviceName,
|
||||
API_SERVICE.dashboardServices
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 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 {
|
||||
deleteCreatedService,
|
||||
goToAddNewServicePage,
|
||||
mySqlConnectionInput,
|
||||
testServiceCreationAndIngestion,
|
||||
updateDescriptionForIngestedTables,
|
||||
uuid,
|
||||
} from '../../common/common';
|
||||
import {
|
||||
API_SERVICE,
|
||||
SERVICE_TYPE,
|
||||
TEAM_ENTITY,
|
||||
} from '../../constants/constants';
|
||||
|
||||
const serviceType = 'Mysql';
|
||||
const serviceName = `${serviceType}.ct%test-${uuid()}`;
|
||||
const tableName = TEAM_ENTITY;
|
||||
const description = `This is ${tableName} description`;
|
||||
|
||||
describe('MySQL Ingestion', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('add and ingest data', () => {
|
||||
goToAddNewServicePage(SERVICE_TYPE.Database);
|
||||
|
||||
const addIngestionInput = () => {
|
||||
cy.get('#root\\/schemaFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
.type(`${Cypress.env('mysqlDatabaseSchema')}{enter}`);
|
||||
};
|
||||
|
||||
const viewIngestionInput = () => {
|
||||
cy.get('.ant-select-selection-item-content')
|
||||
.scrollIntoView()
|
||||
.contains(`${Cypress.env('mysqlDatabaseSchema')}`);
|
||||
};
|
||||
|
||||
testServiceCreationAndIngestion({
|
||||
serviceType,
|
||||
connectionInput: mySqlConnectionInput,
|
||||
addIngestionInput,
|
||||
serviceName,
|
||||
serviceCategory: SERVICE_TYPE.Database,
|
||||
viewIngestionInput,
|
||||
});
|
||||
});
|
||||
|
||||
it('Update table description and verify description after re-run', () => {
|
||||
updateDescriptionForIngestedTables(
|
||||
serviceName,
|
||||
tableName,
|
||||
description,
|
||||
SERVICE_TYPE.Database,
|
||||
'tables'
|
||||
);
|
||||
});
|
||||
|
||||
it('delete created service', () => {
|
||||
deleteCreatedService(
|
||||
SERVICE_TYPE.Database,
|
||||
serviceName,
|
||||
API_SERVICE.databaseServices
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 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 {
|
||||
checkServiceFieldSectionHighlighting,
|
||||
deleteCreatedService,
|
||||
goToAddNewServicePage,
|
||||
testServiceCreationAndIngestion,
|
||||
updateDescriptionForIngestedTables,
|
||||
uuid,
|
||||
} from '../../common/common';
|
||||
import { API_SERVICE, SERVICE_TYPE } from '../../constants/constants';
|
||||
|
||||
const serviceType = 'Snowflake';
|
||||
const serviceName = `${serviceType}-ct-test-${uuid()}`;
|
||||
const tableName = 'CUSTOMER';
|
||||
const schema = 'TPCH_SF1000';
|
||||
const description = `This is ${serviceName} description`;
|
||||
const entityFqn = `${serviceName}.${Cypress.env(
|
||||
'snowflakeDatabase'
|
||||
)}.${schema}.${tableName}`;
|
||||
|
||||
describe('Snowflake Ingestion', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('add and ingest data', { defaultCommandTimeout: 8000 }, () => {
|
||||
goToAddNewServicePage(SERVICE_TYPE.Database);
|
||||
const connectionInput = () => {
|
||||
cy.get('#root\\/username').type(Cypress.env('snowflakeUsername'));
|
||||
checkServiceFieldSectionHighlighting('username');
|
||||
cy.get('#root\\/password').type(Cypress.env('snowflakePassword'));
|
||||
checkServiceFieldSectionHighlighting('password');
|
||||
cy.get('#root\\/account').type(Cypress.env('snowflakeAccount'));
|
||||
checkServiceFieldSectionHighlighting('account');
|
||||
cy.get('#root\\/database').type(Cypress.env('snowflakeDatabase'));
|
||||
checkServiceFieldSectionHighlighting('database');
|
||||
cy.get('#root\\/warehouse').type(Cypress.env('snowflakeWarehouse'));
|
||||
checkServiceFieldSectionHighlighting('warehouse');
|
||||
};
|
||||
|
||||
const addIngestionInput = () => {
|
||||
cy.get('#root\\/schemaFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
|
||||
.type(`${schema}{enter}`);
|
||||
};
|
||||
|
||||
testServiceCreationAndIngestion({
|
||||
serviceType,
|
||||
connectionInput,
|
||||
addIngestionInput,
|
||||
serviceName,
|
||||
serviceCategory: SERVICE_TYPE.Database,
|
||||
});
|
||||
});
|
||||
|
||||
it('Update table description and verify description after re-run', () => {
|
||||
updateDescriptionForIngestedTables(
|
||||
serviceName,
|
||||
tableName,
|
||||
description,
|
||||
SERVICE_TYPE.Database,
|
||||
'tables',
|
||||
entityFqn
|
||||
);
|
||||
});
|
||||
|
||||
it('delete created service', () => {
|
||||
deleteCreatedService(
|
||||
SERVICE_TYPE.Database,
|
||||
serviceName,
|
||||
API_SERVICE.databaseServices
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 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 {
|
||||
deleteCreatedService,
|
||||
goToAddNewServicePage,
|
||||
testServiceCreationAndIngestion,
|
||||
updateDescriptionForIngestedTables,
|
||||
uuid,
|
||||
} from '../../common/common';
|
||||
import { API_SERVICE, SERVICE_TYPE } from '../../constants/constants';
|
||||
|
||||
const serviceType = 'Superset';
|
||||
const serviceName = `${serviceType}-ct-test-${uuid()}`;
|
||||
const tableName = "World Bank's Data";
|
||||
const description = `This is ${serviceName} description`;
|
||||
|
||||
describe('Superset Ingestion', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
});
|
||||
|
||||
it('add and ingest data', () => {
|
||||
goToAddNewServicePage(SERVICE_TYPE.Dashboard);
|
||||
|
||||
// Select Dashboard services
|
||||
cy.get('[data-testid="service-category"]').should('be.visible').click();
|
||||
cy.get('.ant-select-item-option-content')
|
||||
.contains('Dashboard Services')
|
||||
.click();
|
||||
|
||||
const connectionInput = () => {
|
||||
cy.get('#root\\/connection\\/username')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('supersetUsername'));
|
||||
cy.get('#root\\/connection\\/password')
|
||||
.scrollIntoView()
|
||||
.type(Cypress.env('supersetPassword'));
|
||||
cy.get('#root\\/hostPort')
|
||||
.scrollIntoView()
|
||||
.focus()
|
||||
.clear()
|
||||
.type(Cypress.env('supersetHostPort'));
|
||||
};
|
||||
|
||||
const addIngestionInput = () => {
|
||||
cy.get('#root\\/dashboardFilterPattern\\/includes')
|
||||
.scrollIntoView()
|
||||
|
||||
.type(`${tableName}{enter}`);
|
||||
};
|
||||
|
||||
testServiceCreationAndIngestion({
|
||||
serviceType,
|
||||
connectionInput,
|
||||
addIngestionInput,
|
||||
serviceName,
|
||||
type: 'dashboard',
|
||||
serviceCategory: SERVICE_TYPE.Dashboard,
|
||||
});
|
||||
});
|
||||
|
||||
it('Update table description and verify description after re-run', () => {
|
||||
updateDescriptionForIngestedTables(
|
||||
serviceName,
|
||||
tableName,
|
||||
description,
|
||||
SERVICE_TYPE.Dashboard,
|
||||
'dashboards'
|
||||
);
|
||||
});
|
||||
|
||||
it('delete created service', () => {
|
||||
deleteCreatedService(
|
||||
SERVICE_TYPE.Dashboard,
|
||||
serviceName,
|
||||
API_SERVICE.dashboardServices
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -126,6 +126,7 @@ Cypress.Commands.add('storeSession', (username, password) => {
|
||||
.replaceAll('.', '_')}`;
|
||||
|
||||
cy.setCookie(versionCookie, 'true');
|
||||
window.localStorage.setItem('loggedInUsers', 'admin');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -62,9 +62,7 @@ export const EntityListWithV1: FunctionComponent<AntdEntityListProp> = ({
|
||||
return (
|
||||
<div
|
||||
className="right-panel-list-item flex items-center justify-between"
|
||||
data-testid={`${testIDText}-${getEntityName(
|
||||
item as unknown as EntityReference
|
||||
)}`}
|
||||
data-testid={`${testIDText}-${item.name}`}
|
||||
key={item.id}>
|
||||
<div className="flex items-center">
|
||||
<Link
|
||||
|
||||
@ -237,7 +237,7 @@ const ExploreV1: React.FC<ExploreProps> = ({
|
||||
<div className="w-full h-full">
|
||||
{tabItems.length > 0 && (
|
||||
<Layout hasSider className="bg-white">
|
||||
<Sider className="bg-white border-right" width={250}>
|
||||
<Sider className="bg-white border-right" width={270}>
|
||||
<Typography.Paragraph className="explore-data-header">
|
||||
{t('label.data-asset-plural')}
|
||||
</Typography.Paragraph>
|
||||
|
||||
@ -197,6 +197,7 @@ const DatabaseDetails: FunctionComponent = () => {
|
||||
setIsDatabaseDetailsLoading(true);
|
||||
getDatabaseDetailsByFQN(databaseFQN, {
|
||||
fields: 'owner,tags,domain,votes',
|
||||
include: Include.All,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res) {
|
||||
|
||||
@ -80,7 +80,7 @@ function SchemaTablesTab({
|
||||
<div className="d-inline-flex w-max-90">
|
||||
<Link
|
||||
className="break-word"
|
||||
data-testid="table-name-link"
|
||||
data-testid={record.name}
|
||||
to={entityUtilClassBase.getEntityLink(
|
||||
EntityType.TABLE,
|
||||
record.fullyQualifiedName as string
|
||||
|
||||
@ -117,7 +117,7 @@ const MyDataPage = () => {
|
||||
setIsLoadingOwnedData(true);
|
||||
try {
|
||||
const userData = await getUserById(currentUser?.id, {
|
||||
fields: 'follows, owns',
|
||||
fields: 'follows,owns',
|
||||
});
|
||||
|
||||
if (userData) {
|
||||
|
||||
@ -160,6 +160,7 @@ describe('StoredProcedure component', () => {
|
||||
|
||||
expect(getStoredProceduresByFqn).toHaveBeenCalledWith('fqn', {
|
||||
fields: STORED_PROCEDURE_DEFAULT_FIELDS,
|
||||
include: 'all',
|
||||
});
|
||||
});
|
||||
|
||||
@ -178,6 +179,7 @@ describe('StoredProcedure component', () => {
|
||||
|
||||
expect(getStoredProceduresByFqn).toHaveBeenCalledWith('fqn', {
|
||||
fields: STORED_PROCEDURE_DEFAULT_FIELDS,
|
||||
include: 'all',
|
||||
});
|
||||
});
|
||||
|
||||
@ -208,6 +210,7 @@ describe('StoredProcedure component', () => {
|
||||
|
||||
expect(getStoredProceduresByFqn).toHaveBeenCalledWith('fqn', {
|
||||
fields: STORED_PROCEDURE_DEFAULT_FIELDS,
|
||||
include: 'all',
|
||||
});
|
||||
|
||||
expect(await screen.findByText('testDataAssetsHeader')).toBeInTheDocument();
|
||||
@ -234,6 +237,7 @@ describe('StoredProcedure component', () => {
|
||||
|
||||
expect(getStoredProceduresByFqn).toHaveBeenCalledWith('fqn', {
|
||||
fields: STORED_PROCEDURE_DEFAULT_FIELDS,
|
||||
include: 'all',
|
||||
});
|
||||
|
||||
expect(await screen.findByText('testSchemaEditor')).toBeInTheDocument();
|
||||
|
||||
@ -57,6 +57,7 @@ import {
|
||||
StoredProcedure,
|
||||
StoredProcedureCodeObject,
|
||||
} from '../../generated/entity/data/storedProcedure';
|
||||
import { Include } from '../../generated/type/include';
|
||||
import { TagLabel } from '../../generated/type/tagLabel';
|
||||
import { postThread } from '../../rest/feedsAPI';
|
||||
import {
|
||||
@ -172,6 +173,7 @@ const StoredProcedurePage = () => {
|
||||
try {
|
||||
const response = await getStoredProceduresByFqn(storedProcedureFQN, {
|
||||
fields: STORED_PROCEDURE_DEFAULT_FIELDS,
|
||||
include: Include.All,
|
||||
});
|
||||
|
||||
setStoredProcedure(response);
|
||||
|
||||
@ -80,7 +80,7 @@ class SearchClassBase {
|
||||
path: 'dashboards',
|
||||
},
|
||||
[SearchIndex.DASHBOARD_DATA_MODEL]: {
|
||||
label: i18n.t('label.data-model-plural'),
|
||||
label: i18n.t('label.dashboard-data-model-plural'),
|
||||
sortingFields: entitySortingFields,
|
||||
sortField: INITIAL_SORT_FIELD,
|
||||
path: 'dashboardDataModel',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user