| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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 { StaticPropertyUtils } from '../userInput/StaticPropertyUtils'; |
| import { AdapterInput } from '../../model/AdapterInput'; |
| import { ConnectEventSchemaUtils } from './ConnectEventSchemaUtils'; |
| import { DataLakeUtils } from '../datalake/DataLakeUtils'; |
| import { ConnectBtns } from './ConnectBtns'; |
| import { AdapterBuilder } from '../../builder/AdapterBuilder'; |
| import { UserUtils } from '../UserUtils'; |
| import { PipelineUtils } from '../pipeline/PipelineUtils'; |
| |
| export class ConnectUtils { |
| public static testAdapter( |
| adapterConfiguration: AdapterInput, |
| adapterStartFails = false, |
| ) { |
| ConnectUtils.goToConnect(); |
| |
| ConnectUtils.goToNewAdapterPage(); |
| |
| ConnectUtils.selectAdapter(adapterConfiguration.adapterType); |
| |
| ConnectUtils.configureAdapter(adapterConfiguration); |
| |
| if (adapterConfiguration.timestampProperty) { |
| ConnectEventSchemaUtils.markPropertyAsTimestamp( |
| adapterConfiguration.timestampProperty, |
| ); |
| } |
| |
| if (adapterConfiguration.autoAddTimestamp) { |
| ConnectEventSchemaUtils.addTimestampProperty(); |
| } |
| |
| ConnectEventSchemaUtils.finishEventSchemaConfiguration(); |
| |
| ConnectUtils.startAdapter( |
| adapterConfiguration, |
| false, |
| adapterStartFails, |
| ); |
| } |
| |
| public static addAdapter(adapterConfiguration: AdapterInput) { |
| ConnectUtils.goToConnect(); |
| |
| ConnectUtils.goToNewAdapterPage(); |
| |
| ConnectUtils.selectAdapter(adapterConfiguration.adapterType); |
| |
| ConnectUtils.configureAdapter(adapterConfiguration); |
| |
| if (adapterConfiguration.dimensionProperties.length > 0) { |
| adapterConfiguration.dimensionProperties.forEach( |
| dimensionPropertyName => { |
| ConnectEventSchemaUtils.markPropertyAsDimension( |
| dimensionPropertyName, |
| ); |
| }, |
| ); |
| } |
| |
| if (adapterConfiguration.timestampProperty) { |
| ConnectEventSchemaUtils.markPropertyAsTimestamp( |
| adapterConfiguration.timestampProperty, |
| ); |
| } |
| |
| ConnectEventSchemaUtils.finishEventSchemaConfiguration(); |
| } |
| |
| public static addMachineDataSimulator( |
| name: string, |
| persist: boolean = false, |
| ) { |
| const builder = AdapterBuilder.create('Machine_Data_Simulator') |
| .setName(name) |
| .addInput('input', 'wait-time-ms', '1000'); |
| |
| if (persist) { |
| builder.setTimestampProperty('timestamp').setStoreInDataLake(); |
| } |
| |
| const configuration = builder.build(); |
| |
| ConnectUtils.goToConnect(); |
| |
| ConnectUtils.goToNewAdapterPage(); |
| |
| ConnectUtils.selectAdapter(configuration.adapterType); |
| |
| ConnectUtils.configureAdapter(configuration); |
| |
| ConnectEventSchemaUtils.finishEventSchemaConfiguration(); |
| |
| ConnectUtils.startAdapter(configuration); |
| } |
| |
| public static goToConnect() { |
| cy.visit('#/connect'); |
| } |
| |
| public static goToNewAdapterPage() { |
| cy.dataCy('connect-create-new-adapter-button').click(); |
| } |
| |
| public static selectAdapter(name: string) { |
| // Select adapter |
| cy.get('#' + name).click(); |
| } |
| |
| public static configureAdapter(adapterInput: AdapterInput) { |
| StaticPropertyUtils.input(adapterInput.adapterConfiguration); |
| |
| this.configureFormat(adapterInput); |
| |
| ConnectUtils.finishAdapterSettings(); |
| } |
| |
| /** |
| * Clicks next on the adapter settings page |
| */ |
| public static finishAdapterSettings() { |
| // Next Button should not be disabled |
| cy.get('button').contains('Next').parent().should('not.be.disabled'); |
| |
| // Click next |
| cy.get('button').contains('Next').parent().click(); |
| } |
| |
| public static configureFormat(adapterInput: AdapterInput) { |
| if (adapterInput.format) { |
| cy.dataCy('format-' + adapterInput.format) // Find the element with the data-cy attribute |
| .within(() => { |
| cy.get('.mdc-radio').click(); |
| }); |
| |
| StaticPropertyUtils.input(adapterInput.formatConfiguration); |
| } |
| } |
| |
| public static finishEventSchemaConfiguration() { |
| // Click next |
| cy.dataCy('sp-connect-schema-editor', { timeout: 10000 }).should( |
| 'be.visible', |
| ); |
| cy.get('#event-schema-next-button').click(); |
| } |
| |
| public static startAdapter( |
| adapterInput: AdapterInput, |
| noLiveDataView = false, |
| adapterStartFails = false, |
| ) { |
| // Set adapter name |
| cy.dataCy('sp-adapter-name').type(adapterInput.adapterName); |
| |
| if (adapterInput.storeInDataLake) { |
| cy.dataCy('sp-store-in-datalake', { |
| timeout: 5000, |
| }) |
| .should('be.visible') |
| .children() |
| .click(); |
| cy.dataCy('sp-store-in-datalake-timestamp') |
| .click() |
| .get('mat-option') |
| .contains(adapterInput.timestampProperty) |
| .click(); |
| } |
| |
| // Deselect auto start of adapter |
| if (!adapterInput.startAdapter) { |
| ConnectBtns.startAdapterNowCheckbox().parent().click(); |
| } |
| |
| ConnectBtns.adapterSettingsStartAdapter().click(); |
| |
| if (adapterStartFails) { |
| cy.dataCy('sp-exception-details', { |
| timeout: 60000, |
| }).should('be.visible'); |
| } else { |
| if (adapterInput.startAdapter && !noLiveDataView) { |
| cy.dataCy('sp-connect-adapter-success-live-preview', { |
| timeout: 60000, |
| }).should('be.visible'); |
| } else { |
| cy.dataCy('sp-connect-adapter-success-added', { |
| timeout: 60000, |
| }).should('be.visible'); |
| } |
| } |
| |
| this.closeAdapterPreview(); |
| } |
| |
| // Close adapter preview |
| public static closeAdapterPreview() { |
| cy.get('button').contains('Close').parent().click(); |
| } |
| |
| public static deleteAdapter() { |
| // Delete adapter |
| this.goToConnect(); |
| |
| cy.dataCy('delete-adapter').should('have.length', 1); |
| this.clickDelete(); |
| cy.dataCy('adapter-deletion-in-progress', { timeout: 10000 }).should( |
| 'be.visible', |
| ); |
| cy.dataCy('delete-adapter', { timeout: 20000 }).should( |
| 'have.length', |
| 0, |
| ); |
| } |
| |
| public static storeAndStartEditedAdapter() { |
| ConnectUtils.finishEventSchemaConfiguration(); |
| ConnectBtns.storeEditAdapter().click(); |
| ConnectBtns.updateAndMigratePipelines().click(); |
| ConnectUtils.closeAdapterPreview(); |
| ConnectBtns.startAdapter().click(); |
| } |
| |
| public static deleteAdapterAndAssociatedPipelines(switchUserCheck = false) { |
| // Delete adapter and associated pipelines |
| this.goToConnect(); |
| cy.dataCy('delete-adapter').should('have.length', 1); |
| this.clickDelete(); |
| cy.dataCy('delete-adapter-and-associated-pipelines-confirmation', { |
| timeout: 10000, |
| }).should('be.visible'); |
| cy.dataCy( |
| 'delete-adapter-and-associated-pipelines-confirmation', |
| ).click(); |
| cy.dataCy('adapter-deletion-in-progress', { timeout: 10000 }).should( |
| 'be.visible', |
| ); |
| if (switchUserCheck) { |
| UserUtils.switchUser( |
| UserUtils.userWithAdapterAndPipelineAdminRights, |
| ); |
| } |
| this.checkAdapterAndAssociatedPipelinesDeleted(); |
| } |
| |
| // NOTE: this function will leave the adapter and associated pipelines running, |
| // please make sure to clean up after calling this function |
| public static deleteAdapterAndAssociatedPipelinesPermissionDenied() { |
| // Associated pipelines not owned by the user (unless admin) should not be deleted during adapter deletion |
| this.goToConnect(); |
| cy.dataCy('delete-adapter').should('have.length', 1); |
| this.clickDelete(); |
| cy.dataCy('delete-adapter-and-associated-pipelines-confirmation', { |
| timeout: 10000, |
| }).should('be.visible'); |
| cy.dataCy( |
| 'delete-adapter-and-associated-pipelines-confirmation', |
| ).click(); |
| cy.dataCy('adapter-deletion-permission-denied', { |
| timeout: 10000, |
| }).should('be.visible'); |
| cy.get('.sp-dialog-actions').click(); |
| this.checkAdapterNotDeleted(); |
| } |
| |
| public static clickDelete() { |
| cy.dataCy('delete-adapter').click(); |
| cy.dataCy('delete-adapter-confirmation').click(); |
| } |
| |
| public static checkAdapterNotDeleted() { |
| this.goToConnect(); |
| cy.dataCy('delete-adapter', { timeout: 20000 }).should( |
| 'have.length', |
| 1, |
| ); |
| } |
| |
| public static checkAdapterAndAssociatedPipelinesDeleted() { |
| this.goToConnect(); |
| cy.dataCy('delete-adapter', { timeout: 20000 }).should( |
| 'have.length', |
| 0, |
| ); |
| PipelineUtils.goToPipelines(); |
| cy.dataCy('delete-pipeline', { timeout: 10000 }).should( |
| 'have.length', |
| 0, |
| ); |
| } |
| |
| public static setUpPreprocessingRuleTest( |
| overwriteTimestamp: boolean, |
| adapterConfigurationBuilder?: AdapterBuilder, |
| ): AdapterInput { |
| if (!adapterConfigurationBuilder) { |
| adapterConfigurationBuilder = AdapterBuilder.create('File_Stream') |
| .setStoreInDataLake() |
| .setTimestampProperty('timestamp') |
| .addProtocolInput( |
| 'radio', |
| 'speed', |
| 'fastest_\\(ignore_original_time\\)', |
| ) |
| .addProtocolInput('radio', 'replayonce', 'yes') |
| .setName('Adapter to test rules') |
| .setFormat('csv') |
| .addFormatInput('input', ConnectBtns.csvDelimiter(), ';') |
| .addFormatInput('checkbox', ConnectBtns.csvHeader(), 'check'); |
| } |
| |
| if (overwriteTimestamp) { |
| adapterConfigurationBuilder.addProtocolInput( |
| 'checkbox', |
| 'replaceTimestamp', |
| 'check', |
| ); |
| } |
| |
| const adapterConfiguration = adapterConfigurationBuilder.build(); |
| |
| ConnectUtils.goToConnect(); |
| ConnectUtils.goToNewAdapterPage(); |
| ConnectUtils.selectAdapter(adapterConfiguration.adapterType); |
| ConnectUtils.configureAdapter(adapterConfiguration); |
| |
| // wait till schema is shown |
| cy.dataCy('sp-connect-schema-editor', { timeout: 60000 }).should( |
| 'be.visible', |
| ); |
| |
| return adapterConfiguration; |
| } |
| |
| public static startAndValidateAdapter(amountOfProperties: number) { |
| ConnectBtns.startAdapter().should('not.be.disabled'); |
| |
| ConnectBtns.startAdapter().click(); |
| |
| ConnectUtils.validateEventsInPreview(amountOfProperties); |
| } |
| |
| public static getLivePreviewValue(runtimeName: string) { |
| return cy.dataCy(`live-preview-value-${runtimeName}`, { |
| timeout: 10000, |
| }); |
| } |
| |
| public static validateEventsInPreview(amountOfProperties: number) { |
| // View data |
| ConnectBtns.detailsAdapter().click(); |
| |
| // Validate resulting event |
| cy.dataCy('sp-connect-adapter-success-live-preview', { |
| timeout: 20000, |
| }).should('be.visible'); |
| |
| cy.get('tr.mat-mdc-row', { timeout: 10000 }).should( |
| 'have.length', |
| amountOfProperties, |
| ); |
| |
| cy.dataCy('live-preview-table-no-data', { timout: 1000 }).should( |
| 'not.exist', |
| ); |
| } |
| |
| /** |
| * Validates the event schema for an adapter by checking the amount of properties |
| * and the runtime names of the event properties |
| * @param runtimeNames runtime names of the event properties |
| */ |
| public static validateEventSchema(runtimeNames: string[]) { |
| ConnectUtils.goToConnect(); |
| ConnectBtns.detailsAdapter().click(); |
| |
| cy.get('tr.mat-mdc-row').should('have.length', runtimeNames.length); |
| |
| runtimeNames.forEach(name => { |
| cy.get('td.mat-column-runtimeName').contains(name).should('exist'); |
| }); |
| } |
| |
| public static tearDownPreprocessingRuleTest( |
| adapterConfiguration: AdapterInput, |
| expectedFile: string, |
| ignoreTime: boolean, |
| waitTime = 1000, |
| ) { |
| ConnectUtils.startAdapter(adapterConfiguration, true); |
| |
| // Wait till data is stored |
| cy.wait(waitTime); |
| |
| DataLakeUtils.checkResults( |
| 'Adapter to test rules', |
| expectedFile, |
| ignoreTime, |
| ); |
| } |
| |
| public static allAdapterActionsDialog() { |
| // Click next |
| cy.get('button').contains('Next').parent().click(); |
| // Wait for the adapters to start/stop |
| cy.wait(2000); |
| // Close dialog |
| cy.get('button').contains('Close').parent().click(); |
| } |
| |
| public static validateAdapterIsRunning() { |
| ConnectUtils.goToConnect(); |
| ConnectBtns.startAdapter().should('have.length', 0); |
| ConnectBtns.stopAdapter().should('have.length', 1); |
| } |
| |
| public static validateAdapterIsStopped() { |
| ConnectUtils.goToConnect(); |
| ConnectBtns.startAdapter().should('have.length', 1); |
| ConnectBtns.stopAdapter().should('have.length', 0); |
| } |
| |
| public static checkAmountOfAdapters(amount: number) { |
| ConnectUtils.goToConnect(); |
| ConnectBtns.deleteAdapter().should('have.length', amount); |
| } |
| } |