diff --git a/e2e-test/pom.xml b/e2e-test/pom.xml
new file mode 100644
index 000000000..ead3869b6
--- /dev/null
+++ b/e2e-test/pom.xml
@@ -0,0 +1,123 @@
+
+
+
+ 4.0.0
+
+ io.cdap.plugin
+ e2e-test
+ 2.9.0-SNAPSHOT
+
+ 8
+ 8
+
+
+
+ e2e-tests
+
+ e2e-test/src/test
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.18.1
+
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ 3.0.0-M5
+
+
+ TestRunner.java
+
+
+
+
+
+ integration-test
+
+
+
+
+
+
+ net.masterthought
+ maven-cucumber-reporting
+ 5.5.0
+
+
+
+ execution
+ verify
+
+ generate
+
+
+ Cucumber Reports
+ target/cucumber-reports/advanced-reports
+ 1
+ false
+ ${project.build.directory}/cucumber-reports
+
+ **/*.json
+
+ ${project.build.directory}/cucumber-reports
+ true
+
+
+
+
+
+
+
+
+ io.cdap.tests.e2e
+ cdap-e2e-framework
+ 0.0.1-SNAPSHOT
+ test
+
+
+ mysql
+ mysql-connector-java
+ 8.0.26
+
+
+ org.springframework
+ spring-jdbc
+ 5.3.13
+
+
+ com.google.cloud.sql
+ mysql-socket-factory-connector-j-8
+ 1.0.16
+
+
+ com.zaxxer
+ HikariCP
+ 4.0.3
+
+
+
+
+
diff --git a/e2e-test/src/test/features/Cloudsqlmysql_sink_designtime.feature b/e2e-test/src/test/features/Cloudsqlmysql_sink_designtime.feature
new file mode 100755
index 000000000..16735b64d
--- /dev/null
+++ b/e2e-test/src/test/features/Cloudsqlmysql_sink_designtime.feature
@@ -0,0 +1,64 @@
+Feature: CloudSQLMySQl Sink Design Time
+
+ @CLDMYSQL @TC-Mandatory-fields
+ Scenario Outline:Verify CloudSQLMYSQL Sink properties validation errors for mandatory fields
+ Given Open DataFusion Project to configure pipeline
+ When Target is CloudSQLMySQL
+ Then Open CloudSQLMySQL Properties
+ Then Enter the CloudSQLMySQL Sink Properties with blank property ""
+ Then Validate mandatory property error for ""
+ Examples:
+ | property |
+ | referenceName |
+ | database |
+ | connectionName |
+ | tableName |
+ | jdbcPluginName |
+
+ @CLDMYSQL @TC-Invalid-TestData-for-DriverName_Field:
+ Scenario: TC-CLDMYSQL-DSGN-02:Verify Driver Name field validation error with invalid test data
+ Given Open DataFusion Project to configure pipeline
+ When Target is CloudSQLMySQL
+ Then Open CloudSQLMySQL Properties
+ Then Enter Reference Name "clsReferenceNameValid" & Database Name "clsDatabaseName" with Test Data
+ Then Enter Table Name "clsTableNameBQCS" and Connection Name "clsConnectionNameValid"
+ Then Validate Connector properties
+ Then Enter Driver Name with Invalid value for Driver name field "clsDriverNameInvalid"
+ Then Verify invalid Driver name error message is displayed for Driver "clsDriverNameInvalid"
+ Then Verify plugin validation fails with error
+ Then Close the CloudSQLMySQL Properties
+
+ @CLDMYSQL @TC-Invalid-TestData-for-ReferenceName&ConnectionName
+ Scenario: TC-CLDMYSQL-DSGN-03:Verify properties validation errors for invalid test data for Reference name & connection name
+ Given Open DataFusion Project to configure pipeline
+ When Target is CloudSQLMySQL
+ Then Enter Reference Name & Connection Name with Invalid Test Data in Sink
+ Then Verify Reference Name "clsReferenceNameInvalid" Field with Invalid Test Data
+ Then Verify Connection Name "clsConnectionNameInvalid" fields with Invalid Test Data
+ Then Enter Connection Name with private instance type
+ Then Verify Connection Name with private instance type "clsConnectionNameInvalid"
+ Then Close the CloudSQLMySQL Properties
+
+ @CLDMYSQL @TC-Add-Comments
+ Scenario: TC-CLDMYSQL-DSGN-04:Verify the Add Comments functionality for CloudSQL MySQL connector
+ Given Open DataFusion Project to configure pipeline
+ When Target is CloudSQLMySQL
+ Then Add and Save Comments sink "clsPluginComment"
+ Then Validate Sink Comment
+
+ @CLDMYSQL @TC-Edit-Comments
+ Scenario: TC-CLDMYSQL-DSGN-05:Verify the Edit added Comments functionality for CloudSQL MySQL connector
+ Given Open DataFusion Project to configure pipeline
+ When Target is CloudSQLMySQL
+ Then Add and Save Comments sink "clsPluginComment"
+ Then Edit Sink Comments "clsPluginUpdateComment"
+ Then Validate Sink Update Comment
+
+ @CLDMYSQL @TC-Delete-Comments
+ Scenario: TC-CLDMYSQL-DSGN-06:Verify the Delete added Comments functionality for CloudSQL MySQL connector
+ Given Open DataFusion Project to configure pipeline
+ When Target is CloudSQLMySQL
+ Then Add and Save Comments sink "clsPluginComment"
+ Then Edit Sink Comments "clsPluginUpdateComment"
+ Then Delete Comments
+ Then Validate Comment has been deleted successfully
diff --git a/e2e-test/src/test/features/Cloudsqlmysql_sink_runtime.feature b/e2e-test/src/test/features/Cloudsqlmysql_sink_runtime.feature
new file mode 100755
index 000000000..7cca3419b
--- /dev/null
+++ b/e2e-test/src/test/features/Cloudsqlmysql_sink_runtime.feature
@@ -0,0 +1,120 @@
+Feature: BigQuery to CloudSqlMySql and GCS to CloudSqlMySql Runtime
+
+ @CLDMYSQL @TC-Runtime-BigQuery-to-CLOUDSqlMYSQL:
+ Scenario: TC-CLDMYSQL-RNTM-01:Verify user is able to transferred data from BigQuery to CloudSqlMysql with mandatory fields
+ Given Open DataFusion Project to configure pipeline
+ When Source is BigQuery
+ When Target is CloudSQLMySQL
+ Then Link BigQuery to CloudSQLMySQL to establish connection
+ Then Enter the Source BigQuery Properties for table "clsTableNameBQ"
+ Then Validate the Schema
+ Then Verify the Connector status
+ Then Close the BigQuery Properties
+ Then Enter the sink CloudSQLMySQL Properties for table "clsTableNameBQCS"
+ Then Click on Validate button
+ Then Verify the Connector status
+ Then Close the CloudSQLMySQL Properties
+ Then Save the pipeline
+ Then Preview and run the pipeline
+ Then Verify the preview of pipeline is "success"
+ Then Click on PreviewData for CloudSQL MySQL
+ Then Verify Preview output schema matches the outputSchema captured in properties
+ Then Close the Preview
+ Then Pre records count from CloudSQLMySQL table "clsTableNameBQCS"
+ Then Deploy the pipeline
+ Then Run the Pipeline in Runtime
+ Then Wait till pipeline is in running state
+ Then Open and capture Logs
+ Then Verify the pipeline status is "Succeeded"
+ Then Post records count from CloudSQLMySQL table "clsTableNameBQCS"
+ Then Validate the output record count
+ Then Validate successMessage is displayed
+ Then Validate the count of records transferred from BigQuery "clsTableNameBQ" to CloudSqlMySql "clsTableNameBQCS"
+
+ @CLDMYSQL @TC-Runtime-BigQuery-to-CLOUDSqlMYSQL:
+ Scenario: TC-CLDMYSQL-RNTM-02:Verify user is able to transferred data from BigQuery to CloudSqlMysql with filter
+ Given Open DataFusion Project to configure pipeline
+ When Source is BigQuery
+ When Target is CloudSQLMySQL
+ Then Link BigQuery to CloudSQLMySQL to establish connection
+ Then Enter the Source BigQuery Properties for table "clsTableNameBQ1"
+ Then Enter the Source BigQuery with filter "clsFilterBigQuery" option
+ Then Validate the Schema
+ Then Verify the Connector status
+ Then Close the BigQuery Properties
+ Then Enter the sink CloudSQLMySQL Properties for table "clsTableNameBQCS1"
+ Then Click on Validate button
+ Then Verify the Connector status
+ Then Close the CloudSQLMySQL Properties
+ Then Save the pipeline
+ Then Preview and run the pipeline
+ Then Verify the preview of pipeline is "success"
+ Then Click on PreviewData for CloudSQL MySQL
+ Then Verify Preview output schema matches the outputSchema captured in properties
+ Then Close the Preview
+ Then Pre records count from CloudSQLMySQL table "clsTableNameBQCS1"
+ Then Deploy the pipeline
+ Then Run the Pipeline in Runtime
+ Then Wait till pipeline is in running state
+ Then Open and capture Logs
+ Then Verify the pipeline status is "Succeeded"
+ Then Post records count from CloudSQLMySQL table "clsTableNameBQCS1"
+ Then Validate the output record count
+ Then Validate successMessage is displayed
+ Then Validate the count of records transferred from BigQuery "clsTableNameBQ1" to CloudSqlMySql with filter "clsFilterBigQuery"
+
+ @CLDMYSQL @TC-Runtime-GCS-to-CLOUDSQLMYSQL:
+ Scenario: TC-CLDMYSQL-RNTM-03:Verify user is able to transferred data from GCS to CloudSQLMySQL with mandatory fields
+ Given Open DataFusion Project to configure pipeline
+ When Source is GCS bucket
+ When Target is CloudSQLMySQL
+ Then Link GCS to CloudSQLMySQL to establish connection
+ Then Enter the GCS Properties with "clsBucket" GCS bucket and format "clsFormatType"
+ Then Validate the Schema
+ Then Verify the Connector status
+ Then Close the GCS Properties
+ Then Enter the sink CloudSQLMySQL Properties for table "clsTableNameGCSCS"
+ Then Click on Validate button
+ Then Verify the Connector status
+ Then Close the CloudSQLMySQL Properties
+ Then Save the pipeline
+ Then Preview and run the pipeline
+ Then Verify the preview of pipeline is "success"
+ Then Click on PreviewData for CloudSQL MySQL
+ Then Verify Preview output schema matches the outputSchema captured in properties
+ Then Close the Preview
+ Then Deploy the pipeline
+ Then Run the Pipeline in Runtime
+ Then Wait till pipeline is in running state
+ Then Open and capture Logs
+ Then Verify the pipeline status is "Succeeded"
+ Then Validate the output record count
+ Then Validate successMessage is displayed
+
+ @CLDMYSQL @TC-Runtime-GCS-to-CLOUDSQLMYSQL:
+ Scenario: TC-CLDMYSQL-RNTM-04:Verify user is able to Duplicate the pipeline
+ Given Open DataFusion Project to configure pipeline
+ When Source is GCS bucket
+ When Target is CloudSQLMySQL
+ Then Link GCS to CloudSQLMySQL to establish connection
+ Then Enter the GCS Properties with "clsBucket" GCS bucket and format "clsFormatType"
+ Then Validate the Schema
+ Then Verify the Connector status
+ Then Close the GCS Properties
+ Then Enter the sink CloudSQLMySQL Properties for table "clsTableNameGCSCS"
+ Then Click on Validate button
+ Then Verify the Connector status
+ Then Close the CloudSQLMySQL Properties
+ Then Save the pipeline
+ Then Preview and run the pipeline
+ Then Verify the preview of pipeline is "success"
+ Then Click on PreviewData for CloudSQL MySQL
+ Then Verify Preview output schema matches the outputSchema captured in properties
+ Then Close the Preview
+ Then Deploy the pipeline
+ Then Run the Pipeline in Runtime
+ Then Wait till pipeline is in running state
+ Then Verify the pipeline status is "Succeeded"
+ Then Validate the output record count
+ Then Create Duplicate pipeline
+ Then Validate studio is opened with duplicate pipeline
diff --git a/e2e-test/src/test/features/Cloudsqlmysql_source_designtime.feature b/e2e-test/src/test/features/Cloudsqlmysql_source_designtime.feature
new file mode 100755
index 000000000..b60c64fa2
--- /dev/null
+++ b/e2e-test/src/test/features/Cloudsqlmysql_source_designtime.feature
@@ -0,0 +1,95 @@
+Feature: CloudSqlMySql Source Design Time
+
+ @CLDMYSQL @TC-Mandatory-fields
+ Scenario Outline:Verify CloudSQLMYSQL Source properties validation errors for mandatory fields
+ Given Open DataFusion Project to configure pipeline
+ When Source is CloudSQLMySQL
+ Then Open CloudSQLMySQL Properties
+ Then Enter the CloudSQLMySQL Source Properties with blank property ""
+ Then Validate mandatory property error for ""
+ Examples:
+ | property |
+ | referenceName |
+ | database |
+ | connectionName |
+ | importQuery |
+ | jdbcPluginName |
+
+ @CLDMYSQL @TC-Invalid-TestData-for-DriverName_Field:
+ Scenario: TC-CLDMYSQL-DSGN-02:Verify Driver Name field validation error with invalid test data
+ Given Open DataFusion Project to configure pipeline
+ When Source is CloudSQLMySQL
+ Then Open CloudSQLMySQL Properties
+ Then Enter Reference Name "clsReferenceNameValid" & Database Name "clsDatabaseName" with Test Data
+ Then Enter Connection Name "clsConnectionNameValid" and Import Query "clsImportQuery"
+ Then Enter Driver Name with Invalid value for Driver name field "clsDriverNameInvalid"
+ Then Verify invalid Driver name error message is displayed for Driver "clsDriverNameInvalid"
+ Then Verify plugin validation fails with error
+ Then Close the CloudSQLMySQL Properties
+
+ @CLDMYSQL @TC-Invalid-TestData-for-ImportQuery_Field:
+ Scenario: TC-CLDMYSQL-DSGN-03:Verify ImportQuery Field validation error with invalid test data
+ Given Open DataFusion Project to configure pipeline
+ When Source is CloudSQLMySQL
+ Then Open CloudSQLMySQL Properties
+ Then Enter Reference Name "clsReferenceNameValid" & Database Name "clsDatabaseName" with Test Data
+ Then Enter Connection Name "clsConnectionNameValid" and Import Query "clsInvalidImportQuery"
+ Then Validate Connector properties
+ Then Verify invalid import query error message is displayed for import query "clsInvalidImportQuery"
+ Then Verify plugin validation fails with error
+ Then Close the CloudSQLMySQL Properties
+
+ @CLDMYSQL @TC-Invalid-TestData-for-ReferenceName&ConnectionName
+ Scenario: TC-CLDMYSQL-DSGN-04:Verify Reference Name & Connection Name field validation errors with invalid test data
+ Given Open DataFusion Project to configure pipeline
+ When Source is CloudSQLMySQL
+ Then Enter Reference Name & Connection Name with Invalid Test Data and import query "clsImportQuery"
+ Then Verify Reference Name "clsReferenceNameInvalid" Field with Invalid Test Data
+ Then Verify Connection Name "clsConnectionNameInvalid" fields with Invalid Test Data
+ Then Enter Connection Name with private instance type
+ Then Verify Connection Name with private instance type "clsConnectionNameInvalid"
+ Then Close the CloudSQLMySQL Properties
+
+ @CLDMYSQL @TC-Blank-value-error-Validation-for-SplitColumn-Invalid-value-for-Number-of-splits:
+ Scenario: TC-CLDMYSQL-DSGN-05:Verify the Split-By field validation error and invalid Number of Splits
+ Given Open DataFusion Project to configure pipeline
+ When Source is CloudSQLMySQL
+ Then Enter the source CloudSQLMySQL properties with import query "clsImportQuery1" bounding query "clsBoundingQuery"
+ Then Provide blank values in Split column and invalid Number of splits
+ Then Click on Validate button
+ Then Verify Split-by column field error
+ Then Verify Number of splits field error
+ Then Close the CloudSQLMySQL Properties
+
+ @CLDMYSQL @TC-Blank-value-error-Validation-for-Bounding-Query:
+ Scenario: TC-CLDMYSQL-DSGN-06:Verify the Bounding Query validation error when values are not given
+ Given Open DataFusion Project to configure pipeline
+ When Source is CloudSQLMySQL
+ Then Enter the source CloudSQL-MySQL properties with import query "clsImportQuery1" and blank bounding query
+ Then Provide blank values in Split column and invalid Number of splits
+ Then Verify Bounding Query field error
+ Then Close the CloudSQLMySQL Properties
+
+ @CLDMYSQL @TC-Add-Comments
+ Scenario: TC-CLDMYSQL-DSGN-07:Verify the Add Comments functionality for CloudSQL MySQL connector
+ Given Open DataFusion Project to configure pipeline
+ When Source is CloudSQLMySQL
+ Then Add and Save Comments "clsPluginComment"
+ Then Validate Source Comment
+
+ @CLDMYSQL @TC-Edit-Comments
+ Scenario: TC-CLDMYSQL-DSGN-08:Verify the Edit added Comments functionality for CloudSQL MySQL connector
+ Given Open DataFusion Project to configure pipeline
+ When Source is CloudSQLMySQL
+ Then Add and Save Comments "clsPluginComment"
+ Then Edit Source Comments "clsPluginUpdateComment"
+ Then Validate Source Update Comment
+
+ @CLDMYSQL @TC-Delete-Comments
+ Scenario: TC-CLDMYSQL-DSGN-09:Verify the Delete added Comments functionality for CloudSQL MySQL connector
+ Given Open DataFusion Project to configure pipeline
+ When Source is CloudSQLMySQL
+ Then Add and Save Comments "clsPluginComment"
+ Then Edit Source Comments "clsPluginUpdateComment"
+ Then Delete Comments
+ Then Validate Comment has been deleted successfully
diff --git a/e2e-test/src/test/features/Cloudsqlmysql_source_runtime.feature b/e2e-test/src/test/features/Cloudsqlmysql_source_runtime.feature
new file mode 100755
index 000000000..a0c86742d
--- /dev/null
+++ b/e2e-test/src/test/features/Cloudsqlmysql_source_runtime.feature
@@ -0,0 +1,154 @@
+Feature: CloudSqlMySql to BigQuery and CloudSqlMySql to GCS Run-Time
+
+ @CLDMYSQL @TC-Runtime-CLOUDSQLMYSQL-to-BigQuery:
+ Scenario Outline:Verify data transferred from CloudSql-Mysql to BigQuery with mandatory fields
+ Given Open DataFusion Project to configure pipeline
+ When Source is CloudSQLMySQL
+ When Target is BigQuery
+ Then Link CloudSQLMySQL to BigQuery to establish connection
+ Then Enter the source CloudSQLMySQL Properties with import query ""
+ Then Click on Validate button
+ Then Validate the Schema
+ Then Verify the Connector status
+ Then Close the CloudSQLMySQL Properties
+ Then Enter the BigQuery Properties for table "clsMySQLBQTableName"
+ Then Verify the Connector status
+ Then Close the BigQuery Properties
+ Then Save the pipeline
+ Then Preview and run the pipeline
+ Then Verify the preview of pipeline is "success"
+ Then Click on PreviewData for BigQuery
+ Then Verify Preview output schema matches the outputSchema captured in properties
+ Then Close the Preview
+ Then Deploy the pipeline
+ Then Run the Pipeline in Runtime
+ Then Wait till pipeline is in running state
+ Then Open and capture Logs
+ Then Verify the pipeline status is "Succeeded"
+ Then Validate the output record count
+ Then Validate successMessage is displayed
+ Then Validate count of records transferred from importQuery "" to BigQuery in "clsMySQLBQTableName"
+ Then Delete the table "clsMySQLBQTableName"
+ Examples:
+ | importQuery |
+ | clsImportQuery |
+ | clsImportQuery2 |
+
+ @CLDMYSQL @TC-Runtime-CLOUDSQLMYSQL-to-BigQuery:
+ Scenario:Verify user is able to transferred data from CloudSql-Mysql to BigQuery with Advanced
+ Given Open DataFusion Project to configure pipeline
+ When Source is CloudSQLMySQL
+ When Target is BigQuery
+ Then Link CloudSQLMySQL to BigQuery to establish connection
+ Then Enter the source CloudSQLMySQL properties with import query "clsImportQuery1" bounding query "clsBoundingQuery"
+ Then Enter the source CloudSQL-MySQL with Split and Number of splits CloudSQLMySQL properties
+ Then Click on Validate button
+ Then Validate the Schema
+ Then Verify the Connector status
+ Then Close the CloudSQLMySQL Properties
+ Then Enter the BigQuery Properties for table "clsMySQLBQTableName"
+ Then Verify the Connector status
+ Then Close the BigQuery Properties
+ Then Save the pipeline
+ Then Preview and run the pipeline
+ Then Verify the preview of pipeline is "success"
+ Then Click on PreviewData for BigQuery
+ Then Verify Preview output schema matches the outputSchema captured in properties
+ Then Close the Preview
+ Then Deploy the pipeline
+ Then Run the Pipeline in Runtime
+ Then Wait till pipeline is in running state
+ Then Open and capture Logs
+ Then Verify the pipeline status is "Succeeded"
+ Then Validate the output record count
+ Then Validate successMessage is displayed
+ Then Get Count of no of records transferred to BigQuery in "clsMySQLBQTableName"
+ Then Delete the table "clsMySQLBQTableName"
+
+ @CLDMYSQL @TC-Runtime-CLOUDSQLMYSQL-to-GCS:
+ Scenario Outline:Verify user is able to transferred data from CloudSql-Mysql to GCS with mandatory fields
+ Given Open DataFusion Project to configure pipeline
+ Given Cloud Storage bucket should not exist in "projectId" with the name "clsFileBucketCreate"
+ When Source is CloudSQLMySQL
+ When Target is GCS
+ Then Link CloudSQLMySQL to GCS to establish connection
+ Then Enter the source CloudSQLMySQL Properties with import query "clsImportQuery"
+ Then Click on Validate button
+ Then Validate the Schema
+ Then Verify the Connector status
+ Then Close the CloudSQLMySQL Properties
+ Then Enter the GCS Properties and "" file format
+ Then Verify the Connector status
+ Then Close the GCS Properties
+ Then Save the pipeline
+ Then Preview and run the pipeline
+ Then Verify the preview of pipeline is "success"
+ Then Click on PreviewData for GCS
+ Then Verify Preview output schema matches the outputSchema captured in properties
+ Then Close the Preview
+ Then Deploy the pipeline
+ Then Run the Pipeline in Runtime
+ Then Wait till pipeline is in running state
+ Then Verify the pipeline status is "Succeeded"
+ Then Validate the output record count
+ Then Verify the folder created in "projectId" with bucket name "clsFileBucketCreate"
+ Then Open and capture Logs
+ Then Validate successMessage is displayed
+ Examples:
+ | format |
+ | avro |
+ | csv |
+ | parquet |
+ | tsv |
+ | delimited |
+ | json |
+ | orc |
+
+ @CLDMYSQL @TC-Runtime-CLOUDSQLMYSQL-to-GCS:
+ Scenario:Verify user is able to Duplicate the pipeline
+ Given Open DataFusion Project to configure pipeline
+ Given Cloud Storage bucket should not exist in "projectId" with the name "clsFileBucketCreate"
+ When Source is CloudSQLMySQL
+ When Target is GCS
+ Then Link CloudSQLMySQL to GCS to establish connection
+ Then Enter the source CloudSQLMySQL Properties with import query "clsImportQuery"
+ Then Click on Validate button
+ Then Validate the Schema
+ Then Verify the Connector status
+ Then Close the CloudSQLMySQL Properties
+ Then Enter the GCS Properties and "csv" file format
+ Then Verify the Connector status
+ Then Close the GCS Properties
+ Then Save the pipeline
+ Then Preview and run the pipeline
+ Then Verify the preview of pipeline is "success"
+ Then Click on PreviewData for GCS
+ Then Verify Preview output schema matches the outputSchema captured in properties
+ Then Close the Preview
+ Then Deploy the pipeline
+ Then Run the Pipeline in Runtime
+ Then Wait till pipeline is in running state
+ Then Verify the pipeline status is "Succeeded"
+ Then Validate the output record count
+ Then Verify the folder created in "projectId" with bucket name "clsFileBucketCreate"
+ Then Create Duplicate pipeline
+ Then Validate studio is opened with duplicate pipeline
+
+ @CLDMYSQL @TC-Runtime-CLOUDSQLMYSQL-to-BigQuery:
+ Scenario:Verify preview gets failed when incorrect values in Split column CloudSql-Mysql
+ Given Open DataFusion Project to configure pipeline
+ When Source is CloudSQLMySQL
+ When Target is BigQuery
+ Then Link CloudSQLMySQL to BigQuery to establish connection
+ Then Enter the source CloudSQLMySQL properties with import query "clsImportQuery1" bounding query "clsBoundingQuery"
+ Then Enter the incorrect values in split column with number of splits
+ Then Click on Validate button
+ Then Verify the Connector status
+ Then Capture output schema
+ Then Close the CloudSQLMySQL Properties
+ Then Enter the BigQuery Properties for table "clsMySQLBQTableName"
+ Then Verify the Connector status
+ Then Close the BigQuery Properties
+ Then Save the pipeline
+ Then Preview and run the pipeline
+ Then Verify the preview of pipeline is "failed"
diff --git a/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/actions/CdfCloudSqlMySqlActions.java b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/actions/CdfCloudSqlMySqlActions.java
new file mode 100755
index 000000000..82ec428fa
--- /dev/null
+++ b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/actions/CdfCloudSqlMySqlActions.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.
+ */
+package io.cdap.plugin.cloudsqlmysql.actions;
+
+import io.cdap.e2e.pages.actions.CdfStudioActions;
+import io.cdap.e2e.pages.locators.CdfBigQueryPropertiesLocators;
+import io.cdap.e2e.pages.locators.CdfStudioLocators;
+import io.cdap.e2e.utils.SeleniumHelper;
+import io.cdap.plugin.cloudsqlmysql.locators.CdfCloudSqlMySqlLocators;
+import io.cdap.plugin.utils.E2ETestUtils;
+import org.junit.Assert;
+import org.openqa.selenium.WebElement;
+
+import java.io.IOException;
+
+/**
+ * cloudSqlMySql connector related Step Actions.
+ */
+
+public class CdfCloudSqlMySqlActions {
+
+ static {
+ SeleniumHelper.getPropertiesLocators(CdfCloudSqlMySqlLocators.class);
+ SeleniumHelper.getPropertiesLocators(CdfBigQueryPropertiesLocators.class);
+ SeleniumHelper.getPropertiesLocators(CdfStudioLocators.class);
+ }
+
+ public static void clickActionButton() {
+ SeleniumHelper.waitAndClick(CdfCloudSqlMySqlLocators.clickAction);
+ }
+
+ public static void enterReferenceName(String reference) {
+ CdfCloudSqlMySqlLocators.referenceName.sendKeys(reference);
+ }
+
+ public static void enterDriverName(String driver) {
+ CdfCloudSqlMySqlLocators.driverName.sendKeys(driver);
+ }
+
+ public static void enterDefaultDriver(String driverNameValid) {
+ SeleniumHelper.replaceElementValue(CdfCloudSqlMySqlLocators.driverName, driverNameValid);
+ }
+
+ public static void enterDatabaseName(String database) {
+ CdfCloudSqlMySqlLocators.database.sendKeys(database);
+ }
+
+ public static void enterUserName(String username) {
+ CdfCloudSqlMySqlLocators.username.sendKeys(username);
+ }
+
+ public static void enterPassword(String password) {
+ CdfCloudSqlMySqlLocators.password.sendKeys(password);
+ }
+
+ public static void enterConnectionName(String connection) {
+ CdfCloudSqlMySqlLocators.connectionName.sendKeys(connection);
+ }
+
+ public static void enterSplitColumn(String splitColumn) {
+ CdfCloudSqlMySqlLocators.splitColumn.sendKeys(splitColumn);
+ }
+
+ public static void enterNumberOfSplits(String numberOfSplits) {
+ SeleniumHelper.replaceElementValue(CdfCloudSqlMySqlLocators.numberOfSplits, numberOfSplits);
+ }
+
+ public static void enterImportQuery(String query) throws IOException, InterruptedException {
+ CdfCloudSqlMySqlLocators.importQuery.sendKeys(query);
+ }
+
+ public static void enterBoundingQuery(String boundingQuery) throws IOException, InterruptedException {
+ CdfCloudSqlMySqlLocators.boundingQuery.sendKeys(boundingQuery);
+ }
+
+ public static void enterTableName(String table) {
+ CdfCloudSqlMySqlLocators.sqlTableName.sendKeys(table);
+ }
+
+ public static void enterConnectionTimeout(String connectionTimeout) {
+ SeleniumHelper.replaceElementValue(CdfCloudSqlMySqlLocators.connectionTimeout, connectionTimeout);
+ }
+ public static void clickDuplicateButton() {
+ CdfCloudSqlMySqlLocators.actionDuplicateButton.click();
+ }
+
+ public static void closeButton() {
+ CdfCloudSqlMySqlLocators.closeButton.click();
+ }
+
+ public static void clickCloudSqlMySqlProperties() {
+ CdfCloudSqlMySqlLocators.cloudSqlMySqlProperties.click();
+ }
+
+ public static void clickValidateButton() {
+ CdfCloudSqlMySqlLocators.validateButton.click();
+ }
+
+ public static void getSchema() {
+ CdfCloudSqlMySqlLocators.getSchemaButton.click();
+ }
+
+ public static void addComment(String comment) throws IOException {
+ CdfCloudSqlMySqlLocators.addComment.sendKeys(comment);
+ }
+
+ public static void addCommentSink(String sinkComment) throws IOException {
+ CdfCloudSqlMySqlLocators.addCommentSink.sendKeys(sinkComment);
+ }
+
+ public static void updateSourceComment(String updateComment) throws IOException {
+ CdfCloudSqlMySqlLocators.addComment.sendKeys(updateComment);
+ }
+
+ public static void updateSinkComment(String updateComment) throws IOException {
+ CdfCloudSqlMySqlLocators.addCommentSink.sendKeys(updateComment);
+ }
+
+ public static void clickComment() {
+ CdfCloudSqlMySqlLocators.clickComment.click();
+ }
+
+ public static void clickPrivateInstance() {
+ CdfCloudSqlMySqlLocators.instanceType.click();
+ }
+
+ public static void saveComment() throws IOException {
+ CdfCloudSqlMySqlLocators.saveComment.click();
+ }
+
+ public static void editComment() {
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.editComment, 1);
+ CdfCloudSqlMySqlLocators.editComment.click();
+ }
+
+ public static void clickEdit() {
+ CdfCloudSqlMySqlLocators.clickEdit.click();
+ }
+
+ public static void clickDelete() {
+ CdfCloudSqlMySqlLocators.clickDelete.click();
+ }
+
+ public static void validateComment(String expected, String actual) throws IOException {
+ Assert.assertEquals(expected, actual);
+ }
+
+ public static void selectCloudSQLMySQL() throws InterruptedException {
+ SeleniumHelper.waitAndClick(CdfCloudSqlMySqlLocators.cloudSqlMysqlSource);
+ }
+
+ public static void sinkCloudSQLMySQL() {
+ CdfCloudSqlMySqlLocators.sink.click();
+ SeleniumHelper.waitAndClick(CdfCloudSqlMySqlLocators.cloudSqlMysqlSink);
+ }
+
+ public static void selectBigQuerySource() throws InterruptedException {
+ SeleniumHelper.waitAndClick(CdfCloudSqlMySqlLocators.selectBigQuerySource);
+ }
+
+ public static void clickCloudSqlPreviewData() {
+ CdfCloudSqlMySqlLocators.previewData.click();
+ }
+
+ public static void clickPreviewCloseButton() {
+ SeleniumHelper.waitAndClick(CdfCloudSqlMySqlLocators.previewClose);
+ }
+}
diff --git a/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/actions/package-info.java b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/actions/package-info.java
new file mode 100755
index 000000000..b176a9c98
--- /dev/null
+++ b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/actions/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.
+ */
+/**
+ * Package contains step actions for the CloudSqlMySQL features.
+ */
+package io.cdap.plugin.cloudsqlmysql.actions;
diff --git a/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/locators/CdfCloudSqlMySqlLocators.java b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/locators/CdfCloudSqlMySqlLocators.java
new file mode 100755
index 000000000..dd469bd16
--- /dev/null
+++ b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/locators/CdfCloudSqlMySqlLocators.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.
+ */
+package io.cdap.plugin.cloudsqlmysql.locators;
+
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.FindBy;
+import org.openqa.selenium.support.How;
+
+import java.util.List;
+
+/**
+ * CloudSqlMySql Connector Locators.
+ */
+
+public class CdfCloudSqlMySqlLocators {
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='plugin-CloudSQLMySQL-batchsource']")
+ public static WebElement cloudSqlMysqlSource;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='plugin-CloudSQLMySQL-batchsink']")
+ public static WebElement cloudSqlMysqlSink;
+
+ @FindBy(how = How.XPATH, using = "//*[text()='Sink ']")
+ public static WebElement sink;
+
+ @FindBy(how = How.XPATH, using = "//*[contains(@class,'plugin-endpoint_CloudSQL-MySQL')]")
+ public static WebElement fromCloudSqlMysqlSource;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='CloudSQLMySQL-preview-data-btn']")
+ public static WebElement previewData;
+
+ @FindBy(how = How.XPATH, using = "//*[@class='fa fa-remove']")
+ public static WebElement previewClose;
+
+ @FindBy(how = How.XPATH, using = "//*[contains(@class,'plugin-endpoint_BigQuery')]")
+ public static WebElement fromBigQuerySource;
+
+ @FindBy(how = How.XPATH, using = "//*[@title=\"CloudSQL MySQL\"]//following-sibling::div")
+ public static WebElement toCloudSqlMysqlSink;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='referenceName' and @class='MuiInputBase-input']")
+ public static WebElement referenceName;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='jdbcPluginName' and @class='MuiInputBase-input']")
+ public static WebElement driverName;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='database' and @class='MuiInputBase-input']")
+ public static WebElement database;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='importQuery']//textarea")
+ public static WebElement importQuery;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='boundingQuery']//textarea")
+ public static WebElement boundingQuery;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='user' and @class='MuiInputBase-input']")
+ public static WebElement username;
+
+ @FindBy(how = How.XPATH, using = "//*[@placeholder='The password to use to connect to the CloudSQL database']")
+ public static WebElement password;
+
+ @FindBy(how = How.XPATH, using = "//input [@type='radio' and @value='private']")
+ public static WebElement instanceType;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='connectionName' and @class='MuiInputBase-input']")
+ public static WebElement connectionName;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='property-row-error' and contains(text(),'Split-By Field')]")
+ public static WebElement splitColumnError;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='property-row-error' and contains(text(),'Invalid value')]")
+ public static WebElement numberOfSplitError;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='property-row-error' and contains(text(),'Bounding Query must')]")
+ public static WebElement boundingQueryError;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='splitBy' and @class='MuiInputBase-input']")
+ public static WebElement splitColumn;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='numSplits' and @class='MuiInputBase-input']")
+ public static WebElement numberOfSplits;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='tableName' and @class='MuiInputBase-input']")
+ public static WebElement sqlTableName;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='connectionTimeout' and @class='MuiInputBase-input']")
+ public static WebElement connectionTimeout;
+
+ @FindBy(how = How.XPATH, using = "//*[@class='plugin-comments-wrapper ng-scope']")
+ public static WebElement clickComment;
+
+ @FindBy(how = How.XPATH, using = "(//div[contains(@class,'MuiPaper-rounded')])[4]/div/textarea[1]")
+ public static WebElement addComment;
+
+ @FindBy(how = How.XPATH, using = "(//div[contains(@class,'MuiPaper-rounded')])[4]/div[2]/div/p")
+ public static WebElement validateComment;
+
+ @FindBy(how = How.XPATH, using = "(//div[contains(@class,'MuiPaper-rounded')])[3]/div[2]/div/p")
+ public static WebElement validateSinkComment;
+
+ @FindBy(how = How.XPATH, using = "(//*[contains(text(), 'Comment')])[2]")
+ public static WebElement saveComment;
+
+ @FindBy(how = How.XPATH, using = "(//*[contains(@class,'MuiIconButton-sizeSmall') and @tabindex='0'])")
+ public static WebElement editComment;
+
+ @FindBy(how = How.XPATH, using = "(//*[@id='menu-list-grow']//child::li)[1]")
+ public static WebElement clickEdit;
+
+ @FindBy(how = How.XPATH, using = "(//*[@id='menu-list-grow']//child::li)[2]")
+ public static WebElement clickDelete;
+
+ @FindBy(how = How.XPATH, using = "//*[@class='fa fa-remove']")
+ public static WebElement closeButton;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='plugin-properties-validate-btn']")
+ public static WebElement validateButton;
+
+ @FindBy(how = How.XPATH, using = "//*[@class='text-danger']")
+ public static WebElement importQueryError;
+
+ @FindBy(how = How.XPATH, using = "//*[@title=\"CloudSQL MySQL\"]//following-sibling::div")
+ public static WebElement cloudSqlMySqlProperties;
+
+ @FindBy(how = How.XPATH, using = "//*[contains(text(),'Get Schema')]")
+ public static WebElement getSchemaButton;
+
+ @FindBy(how = How.XPATH, using = "//*[@class='btn pipeline-action-btn pipeline-actions-btn']")
+ public static WebElement clickAction;
+
+ @FindBy(how = How.XPATH, using = "//*[contains(text(),'Duplicate')]")
+ public static WebElement actionDuplicateButton;
+
+ @FindBy(how = How.XPATH, using = "(//*[@data-cy='plugin-properties-errors-found']")
+ public static WebElement getSchemaStatus;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='plugin-BigQueryTable-batchsource']")
+ public static WebElement selectBigQuerySource;
+
+ @FindBy(how = How.XPATH, using = "//*[@placeholder='Add a comment']")
+ public static WebElement addCommentSink;
+
+ @FindBy(how = How.XPATH, using = "//*[contains(@class,'Mui-disabled Mui-disabled')]")
+ public static WebElement disabledComment;
+
+ @FindBy(how = How.XPATH, using = "//*[@data-cy='get-schema-btn']//span[text()='Get Schema']")
+ public static WebElement getSchemaLoadComplete;
+
+ @FindBy(how = How.XPATH,
+ using = "//div[@data-cy='Output Schema']//div[@data-cy='schema-fields-list']//*[@placeholder='Field name']")
+ public static List outputSchemaColumnNames;
+
+ @FindBy(how = How.XPATH,
+ using = "//div[@data-cy='Output Schema']//div[@data-cy='schema-fields-list']//select")
+ public static List outputSchemaDataTypes;
+
+ @FindBy(how = How.XPATH,
+ using = "//div[@data-cy='Input Schema']//div[@data-cy='schema-fields-list']//*[@placeholder='Field name']")
+ public static List inputSchemaColumnNames;
+
+ @FindBy(how = How.XPATH,
+ using = "//div[@data-cy='Input Schema']//div[@data-cy='schema-fields-list']//select")
+ public static List inputSchemaDataTypes;
+
+ @FindBy(how = How.XPATH, using = "(//h2[text()='Input Records']/parent::div/div/div/div/div)[1]//div[text()!='']")
+ public static List previewInputRecordColumnNames;
+
+ @FindBy(how = How.XPATH, using = "(//h2[text()='Output Records']/parent::div/div/div/div/div)[1]//div[text()!='']")
+ public static List previewOutputRecordColumnNames;
+
+ @FindBy(how = How.XPATH, using = "//*[@role='tablist']/li[contains(text(),'Properties')]")
+ public static WebElement previewPropertiesTab;
+
+ @FindBy(how = How.XPATH, using = "//*[contains(@data-cy,'GCS') and contains(@data-cy,'-preview-data-btn') and " +
+ "@class='node-preview-data-btn ng-scope']")
+ public static WebElement gcsPreviewData;
+
+}
diff --git a/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/locators/package-info.java b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/locators/package-info.java
new file mode 100755
index 000000000..40c03a877
--- /dev/null
+++ b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/locators/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.
+ */
+/**
+ * Package contains the locators for the cloudSqlMySql features.
+ */
+package io.cdap.plugin.cloudsqlmysql.locators;
diff --git a/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/stepsdesign/CloudSqlMySql.java b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/stepsdesign/CloudSqlMySql.java
new file mode 100755
index 000000000..c34542b6e
--- /dev/null
+++ b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/stepsdesign/CloudSqlMySql.java
@@ -0,0 +1,846 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.
+ */
+package io.cdap.plugin.cloudsqlmysql.stepsdesign;
+
+import io.cdap.e2e.pages.actions.CdfBigQueryPropertiesActions;
+import io.cdap.e2e.pages.actions.CdfGcsActions;
+import io.cdap.e2e.pages.actions.CdfLogActions;
+import io.cdap.e2e.pages.actions.CdfPipelineRunAction;
+import io.cdap.e2e.pages.actions.CdfStudioActions;
+import io.cdap.e2e.pages.locators.CdfStudioLocators;
+import io.cdap.e2e.utils.CdfHelper;
+import io.cdap.e2e.utils.GcpClient;
+import io.cdap.e2e.utils.SeleniumDriver;
+import io.cdap.e2e.utils.SeleniumHelper;
+import io.cdap.plugin.cloudsqlmysql.actions.CdfCloudSqlMySqlActions;
+import io.cdap.plugin.cloudsqlmysql.locators.CdfCloudSqlMySqlLocators;
+import io.cdap.plugin.utils.CloudMySqlClient;
+import io.cdap.plugin.utils.E2ETestConstants;
+import io.cdap.plugin.utils.E2ETestUtils;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import org.junit.Assert;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.support.ui.ExpectedConditions;
+import org.openqa.selenium.support.ui.WebDriverWait;
+import stepsdesign.BeforeActions;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+/**a
+ * CloudSqlMySql related step design.
+ */
+public class CloudSqlMySql implements CdfHelper {
+ public static String folderName;
+ List propertiesSchemaColumnList = new ArrayList<>();
+ Map sourcePropertiesOutputSchema = new HashMap<>();
+ int cloudSqlMySqlPreRecordsCount;
+ int cloudSqlMySqlPostRecordsCount;
+
+ @Given("Open DataFusion Project to configure pipeline")
+ public void openDataFusionProjectToConfigurePipeline() throws IOException, InterruptedException {
+ openCdf();
+ }
+
+ @When("Source is GCS bucket")
+ public void sourceIsGCSBucket() throws InterruptedException {
+ CdfStudioActions.selectGCS();
+ }
+
+ @When("Source is CloudSQLMySQL")
+ public void sourceIsCloudSQLMySQL() throws InterruptedException {
+ CdfCloudSqlMySqlActions.selectCloudSQLMySQL();
+ }
+
+ @When("Source is BigQuery")
+ public void sourceIsBigQuery() throws InterruptedException {
+ CdfCloudSqlMySqlActions.selectBigQuerySource();
+ }
+
+ @When("Target is CloudSQLMySQL")
+ public void targetIsCloudSQLMySQL() {
+ CdfCloudSqlMySqlActions.sinkCloudSQLMySQL();
+ }
+
+ @When("Target is GCS")
+ public void targetIsGCS() throws InterruptedException {
+ CdfStudioActions.sinkGcs();
+ }
+
+ @Then("Open CloudSQLMySQL Properties")
+ public void openCloudSQLMySQLProperties() throws InterruptedException {
+ CdfCloudSqlMySqlActions.clickCloudSqlMySqlProperties();
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.validateButton, 10);
+ }
+
+ @Then("Validate Connector properties")
+ public void validatePipeline() throws InterruptedException {
+ CdfCloudSqlMySqlActions.clickValidateButton();
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.closeButton, 10);
+ }
+
+ @Then("Enter the CloudSQLMySQL Source Properties with blank property {string}")
+ public void enterTheCloudSQLMySQLSourcePropertiesWithBlankProperty(String property) throws IOException,
+ InterruptedException {
+ if (property.equalsIgnoreCase("referenceName")) {
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp("clsDatabaseName"));
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp("clsConnectionNameValid"));
+ CdfCloudSqlMySqlActions.enterImportQuery(E2ETestUtils.pluginProp("clsImportQuery"));
+ } else if (property.equalsIgnoreCase("database")) {
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp("clsReferenceNameValid"));
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp("clsConnectionNameValid"));
+ CdfCloudSqlMySqlActions.enterImportQuery(E2ETestUtils.pluginProp("clsImportQuery"));
+ } else if (property.equalsIgnoreCase("connectionName")) {
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp("clsReferenceNameValid"));
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp("clsDatabaseName"));
+ CdfCloudSqlMySqlActions.enterImportQuery(E2ETestUtils.pluginProp("clsImportQuery"));
+ } else if (property.equalsIgnoreCase("importQuery")) {
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp("clsReferenceNameValid"));
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp("clsDatabaseName"));
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp("clsConnectionNameValid"));
+ } else if (property.equalsIgnoreCase("jdbcPluginName")) {
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp("clsReferenceNameValid"));
+ SeleniumHelper.replaceElementValue(CdfCloudSqlMySqlLocators.driverName, "");
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp("clsDatabaseName"));
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp("clsConnectionNameValid"));
+ CdfCloudSqlMySqlActions.enterImportQuery(E2ETestUtils.pluginProp("clsImportQuery"));
+ } else {
+ Assert.fail("Invalid CloudSQlMySQL source mandatory field " + property);
+ }
+ }
+
+ @Then("Enter the CloudSQLMySQL Sink Properties with blank property {string}")
+ public void enterTheCloudSQLMySQLSinkPropertiesWithBlankProperty(String property) throws IOException,
+ InterruptedException {
+ if (property.equalsIgnoreCase("referenceName")) {
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp("clsDatabaseName"));
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp("clsConnectionNameValid"));
+ CdfCloudSqlMySqlActions.enterTableName(E2ETestUtils.pluginProp("clsTableNameBQCS"));
+ } else if (property.equalsIgnoreCase("database")) {
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp("clsReferenceNameValid"));
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp("clsConnectionNameValid"));
+ CdfCloudSqlMySqlActions.enterTableName(E2ETestUtils.pluginProp("clsTableNameBQCS"));
+ } else if (property.equalsIgnoreCase("connectionName")) {
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp("clsReferenceNameValid"));
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp("clsDatabaseName"));
+ CdfCloudSqlMySqlActions.enterTableName(E2ETestUtils.pluginProp("clsTableNameBQCS"));
+ } else if (property.equalsIgnoreCase("tableName")) {
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp("clsReferenceNameValid"));
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp("clsDatabaseName"));
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp("clsConnectionNameValid"));
+ } else if (property.equalsIgnoreCase("jdbcPluginName")) {
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp("clsReferenceNameValid"));
+ SeleniumHelper.replaceElementValue(CdfCloudSqlMySqlLocators.driverName, "");
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp("clsDatabaseName"));
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp("clsConnectionNameValid"));
+ CdfCloudSqlMySqlActions.enterTableName(E2ETestUtils.pluginProp("clsTableNameBQCS"));
+ } else {
+ Assert.fail("Invalid CloudSQLMYSQL sink mandatory field " + property);
+ }
+ }
+
+ @Then("Validate mandatory property error for {string}")
+ public void validateMandatoryPropertyErrorFor(String property) {
+ CdfGcsActions.clickValidateButton();
+ SeleniumHelper.waitElementIsVisible(CdfStudioLocators.validateButton, 7L);
+ E2ETestUtils.validateMandatoryPropertyError(property);
+ }
+
+ @Then("Enter Reference Name & Connection Name with Invalid Test Data and import query {string}")
+ public void enterReferenceNameConnectionNameWthTheInvalidTestData(String query) throws InterruptedException,
+ IOException {
+ CdfCloudSqlMySqlActions.clickCloudSqlMySqlProperties();
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp("clsReferenceNameInvalid"));
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp("clsDatabaseName"));
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp("clsConnectionNameInvalid"));
+ CdfCloudSqlMySqlActions.enterImportQuery(E2ETestUtils.pluginProp(query));
+ }
+
+ @Then("Validate CloudSQLMySQL properties")
+ public void validateCloudSQLMySQLProperties() {
+ CdfGcsActions.clickValidateButton();
+ String expectedErrorMessage = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MSG_VALIDATION);
+ String actualErrorMessage = CdfStudioLocators.pluginValidationSuccessMsg.getText();
+ Assert.assertEquals(expectedErrorMessage, actualErrorMessage);
+ }
+
+ @Then("Enter Connection Name with private instance type")
+ public void enterTheInvalidPrivate() throws InterruptedException, IOException {
+ CdfCloudSqlMySqlActions.clickPrivateInstance();
+ CdfCloudSqlMySqlActions.clickValidateButton();
+ }
+
+ @Then("Enter Reference Name & Connection Name with Invalid Test Data in Sink")
+ public void enterReferenceNameConnectionNameWithInvalidTestDataInSink() throws InterruptedException, IOException {
+ CdfCloudSqlMySqlActions.clickCloudSqlMySqlProperties();
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp("clsReferenceNameInvalid"));
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp("clsDatabaseName"));
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp("clsConnectionNameInvalid"));
+ CdfCloudSqlMySqlActions.enterTableName(E2ETestUtils.pluginProp("clsTableNameBQCS"));
+ }
+
+ @Then("Verify Reference Name {string} Field with Invalid Test Data")
+ public void verifyReferenceNameFieldWithInvalidTestData(String referenceName) throws InterruptedException {
+ CdfCloudSqlMySqlActions.clickValidateButton();
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.validateButton);
+ String expectedErrorMessage = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MSG_INVALID_REFERENCE_NAME)
+ .replace("REFERENCE_NAME", E2ETestUtils.pluginProp(referenceName));
+ String actualErrorMessage = E2ETestUtils.findPropertyErrorElement("referenceName").getText();
+ Assert.assertEquals(expectedErrorMessage, actualErrorMessage);
+ String actualColor = E2ETestUtils.getErrorColor(E2ETestUtils.findPropertyErrorElement("referenceName"));
+ String expectedColor = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MSG_COLOR);
+ Assert.assertEquals(expectedColor, actualColor);
+ CdfCloudSqlMySqlActions.clickValidateButton();
+ }
+
+ @Then("Verify Connection Name with private instance type {string}")
+ public void verifyConnectionNameWithPrivateInstanceType(String connectionName) throws InterruptedException {
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.validateButton);
+ String expectedErrorMessage = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MSG_INVALID_CONNECTION_PRIVATE)
+ .replace("CONNECTION_NAME", E2ETestUtils.pluginProp(connectionName));
+ String actualErrorMessage = E2ETestUtils.findPropertyErrorElement("connectionName").getText();
+ Assert.assertEquals(expectedErrorMessage, actualErrorMessage);
+ String actualColor = E2ETestUtils.getErrorColor(E2ETestUtils.findPropertyErrorElement("connectionName"));
+ String expectedColor = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MSG_COLOR);
+ Assert.assertEquals(expectedColor, actualColor);
+ CdfCloudSqlMySqlActions.clickValidateButton();
+ }
+
+ @Then("Close the CloudSQLMySQL Properties")
+ public void closeTheCloudSQLMySQLProperties() {
+ CdfCloudSqlMySqlActions.closeButton();
+ }
+
+ @Then("Enter the source CloudSQLMySQL Properties with import query {string}")
+ public void enterTheSourceCloudSQLMySQLPropertiesWithImportQuery(String query) throws IOException,
+ InterruptedException {
+ CdfCloudSqlMySqlActions.clickCloudSqlMySqlProperties();
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp("clsReferenceNameValid"));
+ CdfCloudSqlMySqlActions.enterDefaultDriver(E2ETestUtils.pluginProp("clsDriverNameValid"));
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp("clsDatabaseName"));
+ CdfCloudSqlMySqlActions.enterUserName(System.getenv("Cloud_Mysql_User_Name"));
+ CdfCloudSqlMySqlActions.enterPassword(System.getenv("Cloud_Mysql_Password"));
+ CdfCloudSqlMySqlActions.clickPrivateInstance();
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp("clsConnectionNameValid"));
+ CdfCloudSqlMySqlActions.enterImportQuery(E2ETestUtils.pluginProp(query));
+ CdfCloudSqlMySqlActions.getSchema();
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.getSchemaButton, 30);
+ }
+
+ @Then("Enter the sink CloudSQLMySQL Properties for table {string}")
+ public void enterSinkMandatoryFields(String tableName) throws IOException, InterruptedException {
+ CdfCloudSqlMySqlActions.clickCloudSqlMySqlProperties();
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp("clsReferenceNameValid"));
+ CdfCloudSqlMySqlActions.enterDefaultDriver(E2ETestUtils.pluginProp("clsDriverNameValid"));
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp("clsDatabaseName"));
+ CdfCloudSqlMySqlActions.enterUserName(System.getenv("Cloud_Mysql_User_Name"));
+ CdfCloudSqlMySqlActions.enterPassword(System.getenv("Cloud_Mysql_Password"));
+ CdfCloudSqlMySqlActions.enterTableName(E2ETestUtils.pluginProp(tableName));
+ CdfCloudSqlMySqlActions.clickPrivateInstance();
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp("clsConnectionNameValid"));
+ CdfCloudSqlMySqlActions.enterConnectionTimeout(E2ETestUtils.pluginProp("clsConnectionTimeout"));
+ }
+
+ @Then("Click on Validate button")
+ public void clickValidate() throws IOException, InterruptedException {
+ CdfCloudSqlMySqlActions.clickValidateButton();
+ }
+
+ @Then("Enter Reference Name {string} & Database Name {string} with Test Data")
+ public void enterReferenceNameDatabaseNameWithValidTestData(String referenceName, String databaseName)
+ throws InterruptedException,
+ IOException {
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp(referenceName));
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp(databaseName));
+ }
+
+ @Then("Verify the get schema status")
+ public void verifyTheGetSchemaStatus() throws InterruptedException {
+ Assert.assertFalse(CdfCloudSqlMySqlLocators.getSchemaStatus.isDisplayed());
+ }
+
+ @Then("Validate the Schema")
+ public void validateTheSchema() throws InterruptedException {
+ CdfCloudSqlMySqlActions.getSchema();
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.getSchemaLoadComplete, 10L);
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.outputSchemaColumnNames.get(0), 2L);
+ int index = 0;
+ for (WebElement element : CdfCloudSqlMySqlLocators.outputSchemaColumnNames) {
+ propertiesSchemaColumnList.add(element.getAttribute("value"));
+ sourcePropertiesOutputSchema.put(element.getAttribute("value"),
+ CdfCloudSqlMySqlLocators.outputSchemaDataTypes.get(index).getAttribute("title"));
+ index++;
+ }
+ Assert.assertTrue(propertiesSchemaColumnList.size() >= 1);
+ }
+
+ @Then("Verify the Connector status")
+ public void verifyTheConnectorStatus() throws InterruptedException {
+ CdfStudioActions.clickValidateButton();
+ SeleniumHelper.waitElementIsVisible(CdfStudioLocators.pluginValidationSuccessMsg, 20);
+ Assert.assertTrue(SeleniumDriver.getDriver().findElement
+ (By.xpath("//*[@data-cy='plugin-validation-success-msg']")).isDisplayed());
+ }
+
+ @When("Target is BigQuery")
+ public void targetIsBigQuery() {
+ CdfStudioActions.sinkBigQuery();
+ }
+
+ @Then("Add and Save Comments {string}")
+ public void addComments(String comment) throws InterruptedException, IOException {
+ CdfCloudSqlMySqlActions.clickCloudSqlMySqlProperties();
+ CdfCloudSqlMySqlActions.clickComment();
+ CdfCloudSqlMySqlActions.addComment(E2ETestUtils.pluginProp(comment));
+ CdfCloudSqlMySqlActions.saveComment();
+ }
+
+ @Then("Add and Save Comments sink {string}")
+ public void addCommentSink(String sinkComment) throws InterruptedException, IOException {
+ CdfCloudSqlMySqlActions.clickCloudSqlMySqlProperties();
+ CdfCloudSqlMySqlActions.clickComment();
+ CdfCloudSqlMySqlActions.addCommentSink(E2ETestUtils.pluginProp(sinkComment));
+ CdfCloudSqlMySqlActions.saveComment();
+ }
+
+ @Then("Edit Source Comments {string}")
+ public void editComments(String updateComment) throws InterruptedException, IOException {
+ CdfCloudSqlMySqlActions.editComment();
+ CdfCloudSqlMySqlActions.clickEdit();
+ CdfCloudSqlMySqlActions.updateSourceComment(E2ETestUtils.pluginProp(updateComment));
+ CdfCloudSqlMySqlActions.saveComment();
+ }
+
+ @Then("Edit Sink Comments {string}")
+ public void editSinkComments(String updateComment) throws InterruptedException, IOException {
+ CdfCloudSqlMySqlActions.editComment();
+ CdfCloudSqlMySqlActions.clickEdit();
+ CdfCloudSqlMySqlActions.updateSinkComment(E2ETestUtils.pluginProp(updateComment));
+ CdfCloudSqlMySqlActions.saveComment();
+ }
+
+ @Then("Delete Comments")
+ public void deleteComments() throws InterruptedException {
+ CdfCloudSqlMySqlActions.editComment();
+ CdfCloudSqlMySqlActions.clickDelete();
+ }
+
+ @Then("Validate Source Comment")
+ public void validateSourceComment() throws InterruptedException, IOException {
+ CdfCloudSqlMySqlActions.validateComment
+ (E2ETestUtils.pluginProp("clsPluginValidateComment"),
+ CdfCloudSqlMySqlLocators.validateComment.getText());
+ }
+
+ @Then("Validate Sink Comment")
+ public void validateSinkComment() throws InterruptedException, IOException {
+ CdfCloudSqlMySqlActions.validateComment
+ (E2ETestUtils.pluginProp("clsPluginValidateComment"),
+ CdfCloudSqlMySqlLocators.validateSinkComment.getText());
+ }
+
+ @Then("Validate Source Update Comment")
+ public void validateSourceUpdateComment() throws InterruptedException, IOException {
+ CdfCloudSqlMySqlActions.validateComment
+ (E2ETestUtils.pluginProp("clsPluginValidateUpdateComment"),
+ CdfCloudSqlMySqlLocators.validateComment.getText());
+ }
+
+ @Then("Link CloudSQLMySQL to BigQuery to establish connection")
+ public void linkCldMySqlToBQEstablishConnection() throws InterruptedException {
+ SeleniumHelper.waitElementIsVisible(CdfStudioLocators.toBigQiery);
+ SeleniumHelper.dragAndDrop(CdfCloudSqlMySqlLocators.fromCloudSqlMysqlSource, CdfStudioLocators.toBigQiery);
+ }
+
+ @Then("Link CloudSQLMySQL to GCS to establish connection")
+ public void linkCldMySqlToGCSEstablishConnection() throws InterruptedException {
+ SeleniumHelper.waitElementIsVisible(CdfStudioLocators.toGCS);
+ SeleniumHelper.dragAndDrop(CdfCloudSqlMySqlLocators.fromCloudSqlMysqlSource, CdfStudioLocators.toGCS);
+ }
+
+ @Then("Enter the GCS Properties and {string} file format")
+ public void enterTheGCSProperties(String fileFormat) throws InterruptedException, IOException {
+ CdfGcsActions.gcsProperties();
+ CdfGcsActions.enterReferenceName();
+ CdfGcsActions.enterProjectId();
+ CdfGcsActions.getGcsBucket(E2ETestUtils.pluginProp("clsGCSFilePath"));
+ CdfGcsActions.selectFormat(fileFormat);
+ CdfGcsActions.clickValidateButton();
+ }
+
+ @Then("Enter the Source BigQuery Properties for table {string}")
+ public void enterTheBQSourceProperties(String tableName) throws InterruptedException, IOException {
+ CdfStudioActions.clickProperties("BigQuery");
+ CdfBigQueryPropertiesActions.enterProjectId(E2ETestUtils.pluginProp("clsProjectID"));
+ CdfBigQueryPropertiesActions.enterBigQueryReferenceName(E2ETestUtils.pluginProp("clsReferenceNameValid"));
+ CdfBigQueryPropertiesActions.enterBigQueryDataset(E2ETestUtils.pluginProp("clsDataset"));
+ CdfBigQueryPropertiesActions.enterBigQueryTable(E2ETestUtils.pluginProp(tableName));
+ }
+
+ @Then("Enter the Source BigQuery with filter {string} option")
+ public void enterTheBQSourcePropertiesFilter(String filter) throws InterruptedException, IOException {
+ CdfBigQueryPropertiesActions.enterFilter(E2ETestUtils.pluginProp(filter));
+ }
+
+ @Then("Link GCS to CloudSQLMySQL to establish connection")
+ public void linkGCStoCloudSQLMySQLEstablishConnection() throws InterruptedException {
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.toCloudSqlMysqlSink);
+ SeleniumHelper.dragAndDrop(CdfStudioLocators.fromGCS, CdfCloudSqlMySqlLocators.toCloudSqlMysqlSink);
+ }
+
+ @Then("Enter the GCS Properties with {string} GCS bucket and format {string}")
+ public void enterTheGCSPropertiesWithGCSBucket(String bucket, String format) throws InterruptedException,
+ IOException {
+ CdfGcsActions.gcsProperties();
+ CdfGcsActions.enterReferenceName();
+ CdfGcsActions.enterProjectId();
+ CdfGcsActions.getGcsBucket(E2ETestUtils.pluginProp(bucket));
+ CdfGcsActions.selectFormat(E2ETestUtils.pluginProp(format));
+ CdfGcsActions.skipHeader();
+ CdfGcsActions.getSchema();
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.getSchemaButton, 30);
+ }
+
+ @Then("Run and Preview")
+ public void runAndPreview() throws InterruptedException {
+ CdfStudioActions.runAndPreviewData();
+ }
+
+ @Then("Save and Deploy Pipeline")
+ public void saveAndDeployPipeline() throws InterruptedException {
+ CdfStudioActions.pipelineName();
+ CdfStudioActions.pipelineNameIp("TestPipeline" + UUID.randomUUID().toString());
+ CdfStudioActions.pipelineSave();
+ SeleniumHelper.waitElementIsVisible(CdfStudioLocators.statusBanner);
+ CdfStudioActions.pipelineDeploy();
+ }
+
+ @Then("Run the Pipeline in Runtime")
+ public void runThePipelineInRuntime() throws InterruptedException {
+ CdfPipelineRunAction.runClick();
+ }
+
+ @Then("Wait till pipeline is in running state")
+ public void waitTillPipelineIsInRunningState() throws InterruptedException {
+ Boolean bool = true;
+ WebDriverWait wait = new WebDriverWait(SeleniumDriver.getDriver(), 240000);
+ wait.until(ExpectedConditions.or(ExpectedConditions.
+ visibilityOfElementLocated(By.xpath("//*[@data-cy='Succeeded']")),
+ ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@data-cy='Failed']"))));
+ }
+
+ @Then("Verify the pipeline status is {string}")
+ public void verifyThePipelineStatusIs(String status) {
+ boolean webelement = false;
+ webelement = SeleniumHelper.verifyElementPresent("//*[@data-cy='" + status + "']");
+ Assert.assertTrue(webelement);
+ }
+
+ @Then("Open and capture Logs")
+ public void openAndCaptureLogs() throws FileNotFoundException {
+ captureLogs();
+ }
+
+ @Then("Validate successMessage is displayed")
+ public void validateSuccessMessageIsDisplayed() {
+ CdfLogActions.validateSucceeded();
+ }
+
+ @Then("Click on Advance logs and validate the success message")
+ public void clickOnAdvanceLogsAndValidateTheSuccessMessage() {
+ CdfLogActions.goToAdvanceLogs();
+ CdfLogActions.validateSucceeded();
+ }
+
+ @Then("Enter the BigQuery Properties for table {string}")
+ public void enterTheBigQueryPropertiesForTable(String tableName) throws InterruptedException, IOException {
+ CdfBigQueryPropertiesActions.enterBigQueryProperties(E2ETestUtils.pluginProp(tableName));
+ }
+
+ @Then("Verify Schema in output")
+ public void verifySchemaInOutput() {
+ CdfGcsActions.validateSchema();
+ }
+
+ @Then("Close the GCS Properties")
+ public void closeTheGCSProperties() {
+ CdfGcsActions.closeButton();
+ }
+
+ @Then("Close the BigQuery Properties")
+ public void closeTheBigQueryProperties() {
+ CdfGcsActions.closeButton();
+ }
+
+ @Then("Get Count of no of records transferred to BigQuery in {string}")
+ public void getCountOfNoOfRecordsTransferredToBigQueryIn(String table) throws IOException, InterruptedException {
+ int countRecords;
+ countRecords = GcpClient.countBqQuery(E2ETestUtils.pluginProp(table));
+ BeforeActions.scenario.write("**********No of Records Transferred******************:" + countRecords);
+ Assert.assertEquals(countRecords, recordOut());
+ }
+
+ @Then("Validate count of records transferred from importQuery {string} to BigQuery in {string}")
+ public void validateCountOfRecordsTransferredFromImportQueryToBigQueryIn(String importQuery, String bqTable) throws
+ IOException, InterruptedException {
+ int bqRecordsCount = GcpClient.countBqQuery(E2ETestUtils.pluginProp(bqTable));
+ BeforeActions.scenario.write("**No of Records Transferred to BQ ******************:" + bqRecordsCount);
+ int cloudSqlMySqlRecordsCount = CloudMySqlClient.getRecordsCount(E2ETestUtils.pluginProp(importQuery));
+ BeforeActions.scenario.write("**No of Records fetched with cloudSqlMySql import query ******************:" +
+ cloudSqlMySqlRecordsCount);
+ Assert.assertEquals(cloudSqlMySqlRecordsCount, bqRecordsCount);
+ }
+
+ @Then("Delete the table {string}")
+ public void deleteTheTable(String table) throws IOException, InterruptedException {
+ GcpClient.dropBqQuery(E2ETestUtils.pluginProp(table));
+ BeforeActions.scenario.write("Table Deleted Successfully");
+ }
+
+ @Then("Verify Split-by column field error")
+ public void verifySplitByColumnFieldError() throws Exception {
+ CdfCloudSqlMySqlActions.clickValidateButton();
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.splitColumnError, 10L);
+ String expectedErrorMessage = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MESSAGE_SPLIT_COLUMN_NAME);
+ String actualErrorMessage = CdfCloudSqlMySqlLocators.splitColumnError.getText();
+ Assert.assertEquals(expectedErrorMessage, actualErrorMessage);
+ }
+
+ @Then("Verify Number of splits field error")
+ public void verifyNumberOfSplitsFieldError() throws Exception {
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.numberOfSplitError, 10L);
+ String expectedErrorMessage = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MESSAGE_NUMBER_OF_SPLITS_NAME);
+ String actualErrorMessage = CdfCloudSqlMySqlLocators.numberOfSplitError.getText();
+ Assert.assertEquals(expectedErrorMessage, actualErrorMessage);
+ }
+
+ @Then("Verify Bounding Query field error")
+ public void verifyBoundingQueryFieldError() throws Exception {
+ CdfCloudSqlMySqlActions.clickValidateButton();
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.boundingQueryError, 10L);
+ String expectedErrorMessage = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MESSAGE_BOUNDING_QUERY);
+ String actualErrorMessage = CdfCloudSqlMySqlLocators.boundingQueryError.getText();
+ Assert.assertEquals(expectedErrorMessage, actualErrorMessage);
+ }
+
+ @Then("Link BigQuery to CloudSQLMySQL to establish connection")
+ public void linkBigQueryToCloudSQLMySQLToEstablishConnection() {
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.fromBigQuerySource);
+ SeleniumHelper.dragAndDrop(
+ CdfCloudSqlMySqlLocators.fromBigQuerySource, CdfCloudSqlMySqlLocators.toCloudSqlMysqlSink);
+ }
+
+ @Then("Enter Table Name {string} and Connection Name {string}")
+ public void enterTableNameInTableField(String tableName, String connectionName) throws IOException {
+ CdfCloudSqlMySqlActions.enterTableName(E2ETestUtils.pluginProp(tableName));
+ CdfCloudSqlMySqlActions.clickPrivateInstance();
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp(connectionName));
+ }
+
+ @Then("Enter Connection Name {string} and Import Query {string}")
+ public void enterConnectionImportField(String connection, String query) throws IOException, InterruptedException {
+ CdfCloudSqlMySqlActions.enterUserName(System.getenv("Cloud_Mysql_User_Name"));
+ CdfCloudSqlMySqlActions.enterPassword(System.getenv("Cloud_Mysql_Password"));
+ CdfCloudSqlMySqlActions.clickPrivateInstance();
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp(connection));
+ CdfCloudSqlMySqlActions.enterImportQuery(E2ETestUtils.pluginProp(query));
+ }
+
+ @Then("Replace and enter Invalid Driver value")
+ public void enterInvalidDriverName() throws IOException {
+ SeleniumHelper.replaceElementValue(CdfCloudSqlMySqlLocators.driverName,
+ E2ETestUtils.pluginProp("clsDriverNameInvalid"));
+ }
+
+ @Then("Enter Driver Name with Invalid value for Driver name field {string}")
+ public void enterDriverNameDefaultValue(String driverName) throws IOException {
+ CdfCloudSqlMySqlActions.enterDefaultDriver(E2ETestUtils.pluginProp(driverName));
+ }
+
+ @Then("Create Duplicate pipeline")
+ public void createDuplicatePipeline() throws InterruptedException {
+ CdfCloudSqlMySqlActions.clickActionButton();
+ CdfCloudSqlMySqlActions.clickDuplicateButton();
+ }
+
+ @Then("Verify invalid Driver name error message is displayed for Driver {string}")
+ public void verifyInvalidDriverNameErrorMessageIsDisplayedForDriver(String driverName) {
+ CdfCloudSqlMySqlActions.clickValidateButton();
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.validateButton);
+ String expectedErrorMessage = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MSG_INVALID_DRIVER_NAME)
+ .replaceAll("DRIVER_NAME", E2ETestUtils.pluginProp(driverName));
+ String actualErrorMessage = E2ETestUtils.findPropertyErrorElement("jdbcPluginName").getText();
+ Assert.assertEquals(expectedErrorMessage, actualErrorMessage);
+ String actualColor = E2ETestUtils.getErrorColor(E2ETestUtils.findPropertyErrorElement("jdbcPluginName"));
+ String expectedColor = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MSG_COLOR);
+ Assert.assertEquals(expectedColor, actualColor);
+ }
+
+ @Then("Validate the output record count")
+ public void validateTheOutputRecordCount() {
+ Assert.assertTrue(recordIn() > 0);
+ }
+
+ @Then("Validate studio is opened with duplicate pipeline")
+ public void validateStudioIsOpened() {
+ Assert.assertTrue(CdfStudioLocators.pipelineDeploy.isDisplayed());
+ }
+
+ @Then("Enter the source CloudSQLMySQL properties with import query {string} bounding query {string}")
+ public void enterTheAdvancedSourceCloudSQLMySQLProperties(String importQuery,
+ String boundingQuery) throws IOException,
+ InterruptedException {
+ CdfCloudSqlMySqlActions.clickCloudSqlMySqlProperties();
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp("clsReferenceNameValid"));
+ CdfCloudSqlMySqlActions.enterDefaultDriver(E2ETestUtils.pluginProp("clsDriverNameValid"));
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp("clsDatabaseName"));
+ CdfCloudSqlMySqlActions.enterUserName(System.getenv("Cloud_Mysql_User_Name"));
+ CdfCloudSqlMySqlActions.enterPassword(System.getenv("Cloud_Mysql_Password"));
+ CdfCloudSqlMySqlActions.clickPrivateInstance();
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp("clsConnectionNameValid"));
+ CdfCloudSqlMySqlActions.enterImportQuery(E2ETestUtils.pluginProp(importQuery));
+ CdfCloudSqlMySqlActions.getSchema();
+ CdfCloudSqlMySqlActions.enterBoundingQuery(E2ETestUtils.pluginProp(boundingQuery));
+ }
+
+ @Then("Enter the source CloudSQL-MySQL properties with import query {string} and blank bounding query")
+ public void enterTheSplitColumnInSourceCloudSQLMySQLProperties(String importQuery) throws IOException,
+ InterruptedException {
+ CdfCloudSqlMySqlActions.clickCloudSqlMySqlProperties();
+ CdfCloudSqlMySqlActions.enterReferenceName(E2ETestUtils.pluginProp("clsReferenceNameValid"));
+ CdfCloudSqlMySqlActions.enterDefaultDriver(E2ETestUtils.pluginProp("clsDriverNameValid"));
+ CdfCloudSqlMySqlActions.enterDatabaseName(E2ETestUtils.pluginProp("clsDatabaseName"));
+ CdfCloudSqlMySqlActions.enterUserName(System.getenv("Cloud_Mysql_User_Name"));
+ CdfCloudSqlMySqlActions.enterPassword(System.getenv("Cloud_Mysql_Password"));
+ CdfCloudSqlMySqlActions.clickPrivateInstance();
+ CdfCloudSqlMySqlActions.enterConnectionName(E2ETestUtils.pluginProp("clsConnectionNameValid"));
+ CdfCloudSqlMySqlActions.enterImportQuery(E2ETestUtils.pluginProp(importQuery));
+ }
+
+ @Then("Enter the source CloudSQL-MySQL with Split and Number of splits CloudSQLMySQL properties")
+ public void enterSplitNumberOfSplitsCloudSQLMySQLProperties() throws IOException, InterruptedException {
+ CdfCloudSqlMySqlActions.enterSplitColumn(E2ETestUtils.pluginProp("clsSplitColumn"));
+ CdfCloudSqlMySqlActions.enterNumberOfSplits(E2ETestUtils.pluginProp("clsNumberOfSplits"));
+ }
+
+ @Then("Capture output schema")
+ public void captureOutputSchema() {
+ CdfCloudSqlMySqlActions.getSchema();
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.getSchemaLoadComplete, 10L);
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.outputSchemaColumnNames.get(0), 2L);
+ int index = 0;
+ for (WebElement element : CdfCloudSqlMySqlLocators.outputSchemaColumnNames) {
+ propertiesSchemaColumnList.add(element.getAttribute("value"));
+ sourcePropertiesOutputSchema.put(element.getAttribute("value"),
+ CdfCloudSqlMySqlLocators.outputSchemaDataTypes.get(index).getAttribute("title"));
+ index++;
+ }
+ Assert.assertTrue(propertiesSchemaColumnList.size() >= 1);
+ }
+
+ @Then("Save the pipeline")
+ public void saveThePipeline() {
+ CdfStudioActions.pipelineName();
+ CdfStudioActions.pipelineNameIp("CloudSQLMySQL" + UUID.randomUUID().toString());
+ CdfStudioActions.pipelineSave();
+ SeleniumHelper.waitElementIsVisible(CdfStudioLocators.statusBanner);
+ WebDriverWait wait = new WebDriverWait(SeleniumDriver.getDriver(), 5);
+ wait.until(ExpectedConditions.invisibilityOf(CdfStudioLocators.statusBanner));
+ }
+
+ @Then("Preview and run the pipeline")
+ public void previewAndRunThePipeline() {
+ SeleniumHelper.waitElementIsVisible(CdfStudioLocators.preview, 5);
+ CdfStudioLocators.preview.click();
+ CdfStudioLocators.runButton.click();
+ }
+
+ @Then("Verify the preview of pipeline is {string}")
+ public void verifyThePreviewOfPipelineIs(String previewStatus) {
+ WebDriverWait wait = new WebDriverWait(SeleniumDriver.getDriver(), 180);
+ wait.until(ExpectedConditions.visibilityOfElementLocated(
+ By.xpath("//*[@data-cy='valium-banner-hydrator']//span[contains(text(),'" + previewStatus + "')]")));
+ if (!previewStatus.equalsIgnoreCase("failed")) {
+ wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//*[@data-cy=" +
+ "'valium-banner-hydrator']")));
+ }
+ }
+
+ @Then("Click on PreviewData for CloudSQL MySQL")
+ public void clickOnPreviewDataForCloudSql() {
+ CdfCloudSqlMySqlActions.clickCloudSqlPreviewData();
+ }
+
+ @Then("Verify Preview output schema matches the outputSchema captured in properties")
+ public void verifyPreviewOutputSchemaMatchesTheOutputSchemaCapturedInProperties() {
+ List previewSchemaColumnList = new ArrayList<>();
+ for (WebElement element : CdfCloudSqlMySqlLocators.previewInputRecordColumnNames) {
+ previewSchemaColumnList.add(element.getAttribute("title"));
+ }
+ Assert.assertTrue(previewSchemaColumnList.equals(propertiesSchemaColumnList));
+ CdfCloudSqlMySqlLocators.previewPropertiesTab.click();
+ Map previewSinkInputSchema = new HashMap<>();
+ int index = 0;
+ for (WebElement element : CdfCloudSqlMySqlLocators.inputSchemaColumnNames) {
+ previewSinkInputSchema.put(element.getAttribute("value"),
+ CdfCloudSqlMySqlLocators.inputSchemaDataTypes.get(index).getAttribute("title"));
+ index++;
+ }
+ Assert.assertTrue(previewSinkInputSchema.equals(sourcePropertiesOutputSchema));
+ }
+
+ @Then("Close the Preview")
+ public void closeThePreview() {
+ CdfCloudSqlMySqlActions.clickPreviewCloseButton();
+ CdfStudioActions.previewSelect();
+ }
+
+ @Then("Deploy the pipeline")
+ public void deployThePipeline() {
+ SeleniumHelper.waitElementIsVisible(CdfStudioLocators.pipelineDeploy, 2);
+ CdfStudioActions.pipelineDeploy();
+ }
+
+ @Then("Enter the incorrect values in split column with number of splits")
+ public void enterTheIncorrectValuesInSplitColumnWithDefaultNumberOfSplits() throws IOException {
+ CdfCloudSqlMySqlLocators.splitColumn.sendKeys(E2ETestUtils.pluginProp("clsIncorrectSplit"));
+ SeleniumHelper.replaceElementValue(CdfCloudSqlMySqlLocators.numberOfSplits,
+ E2ETestUtils.pluginProp("clsNumberOfSplits"));
+ }
+
+ @Then("Provide blank values in Split column and invalid Number of splits")
+ public void provideBlankValuesInSplitColumnAndNumberOfSplitsFields() throws IOException {
+ SeleniumHelper.replaceElementValue(CdfCloudSqlMySqlLocators.numberOfSplits,
+ E2ETestUtils.pluginProp("clsInvalidNumberOfSplits"));
+ }
+
+ @Then("Click on PreviewData for BigQuery")
+ public void clickOnPreviewDataForBigQuery() {
+ CdfBigQueryPropertiesActions.clickPreviewData();
+ }
+
+ @Then("Click on PreviewData for GCS")
+ public void clickOnPreviewDataForGCS() {
+ CdfCloudSqlMySqlLocators.gcsPreviewData.click();
+ }
+
+ @Then("Validate Comment has been deleted successfully")
+ public void validateCommentHasBeenDeletedSuccessfully() throws IOException {
+ CdfCloudSqlMySqlActions.closeButton();
+ CdfCloudSqlMySqlActions.clickCloudSqlMySqlProperties();
+ CdfCloudSqlMySqlActions.clickComment();
+ Assert.assertFalse(CdfCloudSqlMySqlLocators.disabledComment.isEnabled());
+ }
+
+ @Then("Verify invalid import query error message is displayed for import query {string}")
+ public void verifyInvalidImportQueryErrorMessageIsDisplayedForImportQuery(String importQuery) {
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.importQueryError, 10L);
+ String expectedErrorMessage = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MSG_INVALID_IMPORT_QUERY);
+ String actualErrorMessage = CdfCloudSqlMySqlLocators.importQueryError.getText();
+ Assert.assertEquals(expectedErrorMessage, actualErrorMessage);
+ }
+
+ @Then("Verify plugin validation fails with error")
+ public void verifyPluginValidationFailsWithError() {
+ CdfStudioActions.clickValidateButton();
+ SeleniumHelper.waitElementIsVisible(CdfStudioLocators.pluginValidationErrorMsg, 10L);
+ String expectedErrorMessage = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MSG_ERROR_FOUND_VALIDATION);
+ String actualErrorMessage = CdfStudioLocators.pluginValidationErrorMsg.getText();
+ Assert.assertEquals(expectedErrorMessage, actualErrorMessage);
+ }
+
+ @Then("Verify Connection Name {string} fields with Invalid Test Data")
+ public void verifyConnectionNameFieldsWithInvalidTestData(String connectionName) {
+ SeleniumHelper.waitElementIsVisible(CdfCloudSqlMySqlLocators.validateButton);
+ String expectedErrorMessage = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MSG_INVALID_CONNECTION_PUBLIC)
+ .replace("CONNECTION_NAME", E2ETestUtils.pluginProp(connectionName));
+ String actualErrorMessage = E2ETestUtils.findPropertyErrorElement("connectionName").getText();
+ Assert.assertEquals(expectedErrorMessage, actualErrorMessage);
+ String actualColor = E2ETestUtils.getErrorColor(E2ETestUtils.findPropertyErrorElement("connectionName"));
+ String expectedColor = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MSG_COLOR);
+ Assert.assertEquals(expectedColor, actualColor);
+ CdfCloudSqlMySqlActions.clickValidateButton();
+ }
+
+ @Given("Cloud Storage bucket should not exist in {string} with the name {string}")
+ public void projectIdCloudStorageBucketShouldNotExistInWithTheName(String projectId, String bucketName) {
+ E2ETestUtils.deleteBucket(E2ETestUtils.pluginProp(projectId), E2ETestUtils.pluginProp(bucketName));
+ }
+
+ @Then("Verify the folder created in {string} with bucket name {string}")
+ public void verifyTheFolderCreatedInWithBucketName(String projectID, String bucketName) {
+ folderName = E2ETestUtils.listObjects(E2ETestUtils.pluginProp(projectID),
+ E2ETestUtils.pluginProp(bucketName));
+ Assert.assertTrue(folderName != null);
+ }
+
+ @Then("Validate the count of records transferred from BigQuery {string} to CloudSqlMySql {string}")
+ public void validateTheCountOfRecordsTransferredFromBigQueryToCloudSqlMySql(String bqTable, String sqlTable) throws
+ IOException, InterruptedException {
+ int bqRecordsCount = GcpClient.countBqQuery(E2ETestUtils.pluginProp(bqTable));
+ BeforeActions.scenario.write("**No of Records Transferred from BQ ******************:" + bqRecordsCount);
+ int cloudSqlMySqlRecordsCount = cloudSqlMySqlPostRecordsCount - cloudSqlMySqlPreRecordsCount;
+ BeforeActions.scenario.write("**No of Records Transferred into the cloudSqlMySql table ******************:" +
+ cloudSqlMySqlRecordsCount);
+ Assert.assertEquals(bqRecordsCount, cloudSqlMySqlRecordsCount);
+ }
+
+ @Then("Pre records count from CloudSQLMySQL table {string}")
+ public void preRecordsCountFromCloudSQLMySQLTable(String sqlTable) {
+ cloudSqlMySqlPreRecordsCount = CloudMySqlClient.countCloudSqlMySqlQuery(E2ETestUtils.pluginProp(sqlTable));
+ }
+
+ @Then("Post records count from CloudSQLMySQL table {string}")
+ public void postRecordsCountFromCloudSQLMySQLTable(String sqlTable) {
+ cloudSqlMySqlPostRecordsCount = CloudMySqlClient.countCloudSqlMySqlQuery(E2ETestUtils.pluginProp(sqlTable));
+ }
+
+ public int getRowCountFromBigQueryTableOnTheBasisOfFilter(String bqTable, String filter)
+ throws IOException, InterruptedException {
+ String projectId = (E2ETestUtils.pluginProp("clsProjectID"));
+ String datasetName = (E2ETestUtils.pluginProp("clsDataset"));
+ String selectQuery = "SELECT count(*) FROM `" + projectId + "." + datasetName + "." + E2ETestUtils.pluginProp
+ (bqTable) + "` WHERE " +
+ E2ETestUtils.pluginProp(filter);
+ int rowCount = GcpClient.getSoleQueryResult(selectQuery).map(Integer::parseInt).orElse(0);;
+ return rowCount;
+ }
+
+ @Then("Validate the count of records transferred from BigQuery {string} to CloudSqlMySql with filter {string}")
+ public void validateTheCountOfRecordsTransferredFromBigQueryToCloudSqlMySqlWithFilter(String bqTable, String filter)
+ throws IOException, InterruptedException {
+ int bqRecordsCount = getRowCountFromBigQueryTableOnTheBasisOfFilter(bqTable, filter);
+ BeforeActions.scenario.write("**No of Records Transferred from BQ ******************:" + bqRecordsCount);
+ int cloudSqlMySqlRecordsCount = cloudSqlMySqlPostRecordsCount - cloudSqlMySqlPreRecordsCount;
+ BeforeActions.scenario.write("**No of Records Transferred into the cloudSqlMySql table ******************:" +
+ cloudSqlMySqlRecordsCount);
+ Assert.assertEquals(bqRecordsCount, cloudSqlMySqlRecordsCount);
+ }
+
+ @Then("Validate Sink Update Comment")
+ public void validateSinkUpdateComment() throws IOException {
+ CdfCloudSqlMySqlActions.validateComment
+ (E2ETestUtils.pluginProp("clsPluginValidateUpdateComment"),
+ CdfCloudSqlMySqlLocators.validateSinkComment.getText());
+ }
+}
diff --git a/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/stepsdesign/package-info.java b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/stepsdesign/package-info.java
new file mode 100755
index 000000000..8a4b3cd79
--- /dev/null
+++ b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/stepsdesign/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.
+ */
+/**
+ * Package contains the stepDesign for the CloudSqlMySql features.
+ */
+package io.cdap.plugin.cloudsqlmysql.stepsdesign;
diff --git a/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/tests/runner/TestRunner.java b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/tests/runner/TestRunner.java
new file mode 100755
index 000000000..66962fb5f
--- /dev/null
+++ b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/tests/runner/TestRunner.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.
+ */
+package io.cdap.plugin.cloudsqlmysql.tests.runner;
+import io.cucumber.junit.Cucumber;
+import io.cucumber.junit.CucumberOptions;
+import org.junit.runner.RunWith;
+
+/**
+ * Test Runner to execute cases.
+ */
+@RunWith(Cucumber.class)
+@CucumberOptions(
+ features = {"src/test/features"},
+ glue = {"io.cdap.plugin.cloudsqlmysql.stepsdesign", "stepsdesign"},
+ tags = {"@CLDMYSQL"},
+ monochrome = true,
+ plugin = {"pretty", "html:target/cucumber-html-report", "json:target/cucumber-reports/cucumber.json",
+ "junit:target/cucumber-reports/cucumber.xml"}
+)
+public class TestRunner {
+}
diff --git a/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/tests/runner/package-info.java b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/tests/runner/package-info.java
new file mode 100755
index 000000000..871ff5163
--- /dev/null
+++ b/e2e-test/src/test/java/io/cdap/plugin/cloudsqlmysql/tests/runner/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.
+ */
+/**
+ * Package contains the runner for the CloudSqlMySQL features.
+ */
+package io.cdap.plugin.cloudsqlmysql.tests.runner;
diff --git a/e2e-test/src/test/java/io/cdap/plugin/utils/CloudMySqlClient.java b/e2e-test/src/test/java/io/cdap/plugin/utils/CloudMySqlClient.java
new file mode 100644
index 000000000..efb8f19f6
--- /dev/null
+++ b/e2e-test/src/test/java/io/cdap/plugin/utils/CloudMySqlClient.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.
+ */
+package io.cdap.plugin.utils;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import org.apache.log4j.Logger;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Optional;
+
+/**
+ * CloudSQLMYSQL database operations client.
+ */
+public class CloudMySqlClient {
+
+ private static final Logger logger = Logger.getLogger(CloudMySqlClient.class);
+ static Connection connection = null;
+
+ private static Connection getCloudMySqlConnection() {
+ if (connection == null) {
+ HikariConfig config = new HikariConfig();
+ config.setJdbcUrl("jdbc:mysql:/" + E2ETestUtils.pluginProp("clsDatabaseName"));
+ config.setUsername(System.getenv("Cloud_Mysql_User_Name"));
+ config.setPassword(System.getenv("Cloud_Mysql_Password"));
+ config.addDataSourceProperty("socketFactory", "com.google.cloud.sql.mysql.SocketFactory");
+ config.addDataSourceProperty("cloudSqlInstance", E2ETestUtils.pluginProp("cloudSqlInstance"));
+ config.addDataSourceProperty("ipTypes", "PRIVATE");
+ config.setMaximumPoolSize(5);
+ config.setMinimumIdle(5);
+ config.setConnectionTimeout(10000);
+ config.setIdleTimeout(600000);
+ config.setMaxLifetime(1800000);
+ HikariDataSource pool = new HikariDataSource(config);
+ try {
+ connection = pool.getConnection();
+ } catch (SQLException e) {
+ logger.error("Error while creating CloudSqlMySql connection : " + e);
+ }
+ }
+ return connection;
+ }
+
+ public static Optional getSoleQueryResult(String query) {
+ String outputRowValue = null;
+ try (PreparedStatement createTableStatement = getCloudMySqlConnection().prepareStatement(query);) {
+ ResultSet resultSet = createTableStatement.executeQuery();
+ if (resultSet.next()) {
+ outputRowValue = resultSet.getString(1);
+ }
+ } catch (SQLException e) {
+ logger.error("Error while executing CloudSqlMySql query : " + e);
+ }
+ return Optional.ofNullable(outputRowValue);
+ }
+
+ public static int countCloudSqlMySqlQuery(String table) {
+ String query = "SELECT count(*) from " + table;
+ return getSoleQueryResult(query).map(Integer::parseInt).orElse(0);
+ }
+
+ public static int getRecordsCount(String query) {
+ int count = 0;
+ try (PreparedStatement createTableStatement = getCloudMySqlConnection()
+ .prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) {
+ ResultSet resultSet = createTableStatement.executeQuery();
+ if (resultSet.last()) {
+ count = resultSet.getRow();
+ }
+ } catch (SQLException e) {
+ logger.error("Error while getting CloudSqlMySQL records count : " + e);
+ }
+ return count;
+ }
+}
diff --git a/e2e-test/src/test/java/io/cdap/plugin/utils/E2ETestConstants.java b/e2e-test/src/test/java/io/cdap/plugin/utils/E2ETestConstants.java
new file mode 100644
index 000000000..5fa1f1a2e
--- /dev/null
+++ b/e2e-test/src/test/java/io/cdap/plugin/utils/E2ETestConstants.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.
+ */
+package io.cdap.plugin.utils;
+
+/**
+ * E2E test constants.
+ */
+public class E2ETestConstants {
+ public static final String ERROR_MSG_VALIDATION = "errorMessageValidation";
+ public static final String ERROR_MSG_INVALID_DRIVER_NAME = "errorMessageDriverName";
+ public static final String ERROR_MSG_COLOR = "errorMessageColor";
+ public static final String ERROR_MSG_MANDATORY = "errorMessageMandatory";
+ public static final String ERROR_MSG_ERROR_FOUND_VALIDATION = "errorMessageErrorFoundValidation";
+ public static final String ERROR_MSG_INVALID_IMPORT_QUERY = "errorMessageImportQuery";
+ public static final String ERROR_MSG_INVALID_REFERENCE_NAME = "errorMessageReferenceName";
+ public static final String ERROR_MSG_INVALID_CONNECTION_PUBLIC = "errorMessagePublicConnectionName";
+ public static final String ERROR_MSG_INVALID_CONNECTION_PRIVATE = "errorMessagePrivateConnectionName";
+ public static final String ERROR_MESSAGE_SPLIT_COLUMN_NAME = "errorMessageSplitColumn";
+ public static final String ERROR_MESSAGE_NUMBER_OF_SPLITS_NAME = "errorMessageNumberOfSplit";
+ public static final String ERROR_MESSAGE_BOUNDING_QUERY = "errorMessageBoundingQuery";
+}
diff --git a/e2e-test/src/test/java/io/cdap/plugin/utils/E2ETestUtils.java b/e2e-test/src/test/java/io/cdap/plugin/utils/E2ETestUtils.java
new file mode 100644
index 000000000..072b04e2e
--- /dev/null
+++ b/e2e-test/src/test/java/io/cdap/plugin/utils/E2ETestUtils.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.
+ */
+package io.cdap.plugin.utils;
+
+import com.google.api.gax.paging.Page;
+import com.google.cloud.storage.Blob;
+import com.google.cloud.storage.Bucket;
+import com.google.cloud.storage.Storage;
+import com.google.cloud.storage.StorageOptions;
+import io.cdap.e2e.utils.ConstantsUtil;
+import io.cdap.e2e.utils.SeleniumDriver;
+import org.apache.log4j.Logger;
+import org.junit.Assert;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+import stepsdesign.BeforeActions;
+
+import java.io.IOException;
+import java.util.Properties;
+
+/**
+ * E2ETestUtils contains the helper functions.
+ */
+
+public class E2ETestUtils {
+ private static Properties pluginProperties = new Properties();
+ private static Properties errorProperties = new Properties();
+ private static final Logger logger = Logger.getLogger(E2ETestUtils.class);
+
+ static {
+
+ try {
+ pluginProperties.load(E2ETestUtils.class.getResourceAsStream("/pluginParameters.properties"));
+ errorProperties.load(E2ETestUtils.class.getResourceAsStream("/errorMessage.properties"));
+ } catch (IOException e) {
+ logger.error("Error while reading properties file" + e);
+ }
+ }
+
+ public static String pluginProp(String property) {
+ return pluginProperties.getProperty(property);
+ }
+
+ public static String errorProp(String property) {
+ return errorProperties.getProperty(property);
+ }
+
+ public static void validateMandatoryPropertyError(String property) {
+ String expectedErrorMessage = errorProp(E2ETestConstants.ERROR_MSG_MANDATORY)
+ .replaceAll("PROPERTY", property);
+ String actualErrorMessage = findPropertyErrorElement(property).getText();
+ Assert.assertEquals(expectedErrorMessage, actualErrorMessage);
+ String actualColor = E2ETestUtils.getErrorColor(E2ETestUtils.findPropertyErrorElement(property));
+ String expectedColor = E2ETestUtils.errorProp(E2ETestConstants.ERROR_MSG_COLOR);
+ Assert.assertEquals(expectedColor, actualColor);
+ }
+
+ public static WebElement findPropertyErrorElement(String property) {
+ return SeleniumDriver.getDriver().findElement(
+ By.xpath("//*[@data-cy='" + property + "']/following-sibling::div[@data-cy='property-row-error']"));
+ }
+
+ public static String getErrorColor(WebElement element) {
+ String color = element.getCssValue(ConstantsUtil.COLOR);
+ String[] hexValue = color.replace("rgba(", "").
+ replace(")", "").split(",");
+ int hexValue1 = Integer.parseInt(hexValue[0]);
+ hexValue[1] = hexValue[1].trim();
+ int hexValue2 = Integer.parseInt(hexValue[1]);
+ hexValue[2] = hexValue[2].trim();
+ int hexValue3 = Integer.parseInt(hexValue[2]);
+ return String.format("#%02x%02x%02x", hexValue1, hexValue2, hexValue3);
+ }
+
+ public static void deleteBucket(String projectId, String bucketName) {
+ try {
+ Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
+ Bucket bucket = storage.get(bucketName);
+ StorageOptions.Builder optionsBuilder = StorageOptions.newBuilder();
+ Iterable blobs = storage.list(bucketName,
+ Storage.BlobListOption.prefix("")).iterateAll();
+ for (Blob blob : blobs) {
+ blob.delete(Blob.BlobSourceOption.generationMatch());
+ }
+
+ storage.delete(bucketName,
+ Storage.BucketSourceOption.userProject(projectId));
+ bucket.delete();
+ BeforeActions.scenario.write("Bucket " + bucket.getName() + " was deleted");
+ } catch (Exception e) {
+ BeforeActions.scenario.write("Bucket doesn't exist");
+ }
+ }
+
+ public static String listObjects(String projectId, String bucketName) {
+ String folderName = null;
+ Storage storage = StorageOptions.newBuilder().setProjectId(projectId).build().getService();
+ Page blobs = storage.list(bucketName);
+ for (Blob blob : blobs.iterateAll()) {
+ if (blob.getName().contains("part")) {
+ folderName = blob.getName();
+ break;
+ }
+ }
+ return folderName;
+ }
+}
diff --git a/e2e-test/src/test/java/io/cdap/plugin/utils/package-info.java b/e2e-test/src/test/java/io/cdap/plugin/utils/package-info.java
new file mode 100644
index 000000000..aa77fdc52
--- /dev/null
+++ b/e2e-test/src/test/java/io/cdap/plugin/utils/package-info.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright © 2021 Cask Data, Inc.
+ *
+ * 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.
+ */
+/**
+ * Package contains the helper utils.
+ */
+package io.cdap.plugin.utils;
diff --git a/e2e-test/src/test/resources/errorMessage.properties b/e2e-test/src/test/resources/errorMessage.properties
new file mode 100644
index 000000000..34ab74e3b
--- /dev/null
+++ b/e2e-test/src/test/resources/errorMessage.properties
@@ -0,0 +1,17 @@
+errorMessageColor=#a40403
+errorMessageMandatory=Required property 'PROPERTY' has no value.
+errorMessageSplitColumn=Split-By Field Name must be specified if Number of Splits is not set to 1.
+errorMessageNumberOfSplit=Invalid value for numSplits '0'. Must be at least 1.
+errorMessageBoundingQuery=Bounding Query must be specified if Number of Splits is not set to 1.
+errorMessageValidation=No errors found.
+errorMessageErrorFoundValidation=1 error found
+errorMessageDriverName=Unable to load JDBC Driver class for plugin name 'DRIVER_NAME'. Ensure that the \
+ plugin 'DRIVER_NAME' of type 'jdbc' containing the driver has been installed correctly.
+errorMessageImportQuery=SQL error while getting query schema: You have an error in your SQL syntax; check the manual \
+ that corresponds to your MySQL server version for the right syntax to use near 'query' at line 1
+errorMessageReferenceName=Invalid reference name 'REFERENCE_NAME'. Supported characters are: letters, numbers, \
+ and '_', '-', '.', or '$'.
+errorMessagePublicConnectionName=Connection Name must be in the format :: to \
+ connect to a public CloudSQL MySQL instance.
+errorMessagePrivateConnectionName=Enter the internal IP address of the Compute Engine VM cloudsql proxy is running on,\
+ \ to connect to a private CloudSQL MySQL instance.
diff --git a/e2e-test/src/test/resources/pluginParameters.properties b/e2e-test/src/test/resources/pluginParameters.properties
new file mode 100644
index 000000000..617c45bbd
--- /dev/null
+++ b/e2e-test/src/test/resources/pluginParameters.properties
@@ -0,0 +1,41 @@
+projectId=cdf-athena
+dataset=test_automation
+windowSize=1920x1040
+clsErrorMessageColor=#a40403
+clsPluginComment=Comment for Plugin
+clsPluginUpdateComment=CloudSQL MySQL
+clsPluginValidateComment=Comment for Plugin
+clsPluginValidateUpdateComment=CloudSQL MySQL Comment for Plugin
+clsReferenceNameInvalid=#@#@#@#@#@
+clsReferenceNameValid=TestReference
+clsDriverNameInvalid=@@!67RTC
+clsDriverNameValid=cloudsql-mysql
+clsDatabaseName=cdfdb
+cloudSqlInstance=cdf-athena:europe-west1:cdf-qa-testdb
+ipTypes=PRIVATE
+clsConnectionNameInvalid=10
+clsImportQuery=select * from cdftest4;
+clsInvalidImportQuery=import query;
+clsImportQuery1=select * from cdftest4 where $CONDITIONS;
+clsImportQuery2=select * from cdftest4 where parent_id=2056;
+clsBoundingQuery=select MIN(s_no),MAX(s_no) from cdftest4;
+clsConnectionNameValid=10.232.15.232
+clsConnectionTimeout=20
+clsSplitColumn=s_no
+clsIncorrectSplit=@#*()
+clsNumberOfSplits=3
+clsInvalidNumberOfSplits=0
+clsTableNameBQCS=cdftest2
+clsTableNameGCSCS=cdftest3
+clsTableNameBQCS1=cdftest4
+clsPathGCS=gs://cdf-athena-test/cloudmysql
+clsDataset=test_abc
+clsProjectID=cdf-athena
+clsTableNameBQ=tableabc
+clsTableNameBQ1=tablecloud
+clsBucket=gs://cdf-athena-test/TestingGCS.csv
+clsFormatType=csv
+clsFilterBigQuery=country_code='RS'
+clsMySQLBQTableName=DemoCheck1
+clsGCSFilePath=gs://cloudmysqlfilegcs
+clsFileBucketCreate=cloudmysqlfilegcs
diff --git a/pom.xml b/pom.xml
index f305ecea5..57f3033aa 100644
--- a/pom.xml
+++ b/pom.xml
@@ -469,6 +469,14 @@
**/org/apache/hadoop/**
**/resources/**
+ e2e-test/**/*.properties
+ e2e-test/**/*.feature
+ e2e-test/**/cucumber**/**
+ e2e-test/**/maven-status/**
+ e2e-test/**/failsafe-reports/**
+ e2e-test/**/e2e-debug/**
+ e2e-test/**/*-result.xml
+ e2e-test/e2e-test.iml