From 7499d20ba7baedb15e246544a873d175f05ff934 Mon Sep 17 00:00:00 2001 From: asirvadAbrahamVarghese Date: Tue, 16 Sep 2025 14:38:13 +0530 Subject: [PATCH 1/4] Added automated tests with cypress for cloud-provider form --- .../Clouds/Providers/cloud_provider.cy.js | 4322 +++++++++++++++++ 1 file changed, 4322 insertions(+) create mode 100644 cypress/e2e/ui/Compute/Clouds/Providers/cloud_provider.cy.js diff --git a/cypress/e2e/ui/Compute/Clouds/Providers/cloud_provider.cy.js b/cypress/e2e/ui/Compute/Clouds/Providers/cloud_provider.cy.js new file mode 100644 index 00000000000..0d5566ca323 --- /dev/null +++ b/cypress/e2e/ui/Compute/Clouds/Providers/cloud_provider.cy.js @@ -0,0 +1,4322 @@ +/* eslint-disable no-undef */ +import { flashClassMap } from '../../../../../support/assertions/assertion_constants'; + +// Menu options +const COMPUTE_MENU_OPTION = 'Compute'; +const CLOUDS_AUTOMATION_MENU_OPTION = 'Clouds'; +const PROVIDERS_MENU_OPTION = 'Providers'; + +// Data table component URL +const CLOUD_PROVIDERS_LIST_URL = '/ems_cloud/show_list#/'; + +// Config options +const CONFIG_TOOLBAR_BUTTON = 'Configuration'; +const ADD_PROVIDER_CONFIG_OPTION = 'Add a New Cloud Provider'; +const EDIT_PROVIDER_CONFIG_OPTION = 'Edit Selected Cloud Provider'; +const REMOVE_PROVIDER_CONFIG_OPTION = 'Remove Cloud Providers from Inventory'; +const REFRESH_CONFIG_OPTION = 'Refresh Relationships and Power States'; + +// Provider types +const PROVIDER_TYPE_VMWARE_VCLOUD = 'VMware vCloud'; +const PROVIDER_TYPE_AZURE_STACK = 'Azure Stack'; +const PROVIDER_TYPE_IBM_CLOUD_VPC = 'IBM Cloud VPC'; +const PROVIDER_TYPE_IBM_POWER_SYSTEMS = 'IBM Power Systems Virtual Servers'; +const PROVIDER_TYPE_GOOGLE_COMPUTE = 'Google Compute Engine'; +const PROVIDER_TYPE_ORACLE_CLOUD = 'Oracle Cloud'; +const PROVIDER_TYPE_AZURE = 'Azure'; +const PROVIDER_TYPE_AMAZON_EC2 = 'Amazon EC2'; +const PROVIDER_TYPE_IBM_POWERVC = 'IBM PowerVC'; +const PROVIDER_TYPE_IBM_CIC = 'IBM Cloud Infrastructure Center'; +const PROVIDER_TYPE_OPENSTACK = 'OpenStack'; + +// Other select options +const EVENT_STREAM_TYPE_AMQP = 'AMQP'; +const EVENT_STREAM_TYPE_STF = 'STF'; +const ENABLED_SELECT_OPTION = 'Enabled'; +const API_VERSION_TYPE_V3 = 'Keystone V3'; +const API_VERSION_TYPE_V5 = 'vCloud API 5.5'; +const API_VERSION_TYPE_V9 = 'vCloud API 9.0'; +const API_VERSION_TYPE_2017 = 'V2017_03_09'; +const ZONE_OPTION_DEFAULT = 'default'; +const REGION_OPTION_CENTRAL_INDIA = 'Central India'; +const REGION_OPTION_CENTRAL_US = 'Central US'; +const REGION_OPTION_HYDERABAD = 'ap-hyderabad-1'; +const REGION_OPTION_MELBOURNE = 'ap-melbourne-1'; +const REGION_OPTION_AUSTRALIA = 'Australia (Sydney)'; +const REGION_OPTION_SPAIN = 'EU Spain (Madrid)'; +const REGION_OPTION_CANADA = 'Canada (Central)'; +const REGION_OPTION_ASIA_PACIFIC = 'Asia Pacific (Malaysia)'; +const SECURITY_PROTOCOL_SSL = 'SSL'; +const SECURITY_PROTOCOL_NON_SSL = 'Non-SSL'; + +// Field labels +const TYPE_FIELD_LABEL = 'Type'; +const NAME_FIELD_LABEL = 'Name'; +const ZONE_FIELD_LABEL = 'Zone'; +const API_VERSION_FIELD_LABEL = 'API Version'; +const HOSTNAME_FIELD_LABEL = 'Hostname (or IPv4 or IPv6 address)'; +const API_PORT_FIELD_LABEL = 'API Port'; +const USERNAME_FIELD_LABEL = 'Username'; +const PASSWORD_FIELD_LABEL = 'Password'; +const SECURITY_PROTOCOL_FIELD_LABEL = 'Security Protocol'; +const REGION_FIELD_LABEL = 'Region'; +const TENANT_ID_FIELD_LABEL = 'Tenant ID'; +const DOMAIN_ID_FIELD_LABEL = 'Domain ID'; +const USER_ID_FIELD_LABEL = 'User ID'; +const PUBLIC_KEY_FIELD_LABEL = 'Public Key'; +const PRIVATE_KEY_FIELD_LABEL = 'Private Key'; +const IBM_CLOUD_COMMON_FIELD_LABEL = 'IBM Cloud'; +const SERVICE_COMMON_FIELD_LABEL = 'Service'; +const PROJECT_ID_FIELD_LABEL = 'Project ID'; +const SUBSCRIPTION_ID_FIELD_LABEL = 'Subscription ID'; +const ENDPOINT_URL_FIELD_LABEL = 'Endpoint URL'; +const CLIENT_ID_FIELD_LABEL = 'Client ID'; +const CLIENT_KEY_FIELD_LABEL = 'Client Key'; +const ASSUME_ROLE_ARN_FIELD_LABEL = 'Assume role ARN'; +const ACCESS_KEY_ID_FIELD_LABEL = 'Access Key ID'; +const SECRET_ACCESS_KEY_FIELD_LABEL = 'Secret Access Key'; +const SMARTSTATE_DOCKER_TAB_LABEL = 'SmartState Docker'; +const PROVIDER_REGION_FIELD_LABEL = 'Provider Region'; +const OPENSTACK_INFRA_PROVIDER_FIELD_LABEL = 'Openstack Infra Provider'; +const POWERVC_API_ENDPOINT_FIELD_LABEL = + 'PowerVC API Endpoint (Hostname or IPv4/IPv6 address)'; +const ANSIBLE_ACCESS_METHOD_FIELD_LABEL = 'Ansible Access Method'; +const TENANT_MAPPING_ENABLED_FIELD_LABEL = 'Tenant Mapping Enabled'; +const API_USERNAME_FIELD_LABEL = 'API Username'; +const API_PASSWORD_FIELD_LABEL = 'API Password'; +const POWERVC_COMMON_FIELD_LABEL = 'PowerVC'; + +// Tab labels +const EVENTS_TAB_LABEL = 'Events'; +const METRICS_TAB_LABEL = 'Metrics'; +const RSA_KEY_PAIR_TAB_LABEL = 'RSA key pair'; +const IMAGE_EXPORT_TAB_LABEL = 'Image Export'; + +// Field values +const TEST_NAME = 'Test Name:'; +const AZURE_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_AZURE}`; +const VMWARE_VCLOUD_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_VMWARE_VCLOUD}`; +const ORACLE_CLOUD_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_ORACLE_CLOUD}`; +const IBM_CLOUD_VPC_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_IBM_CLOUD_VPC}`; +const IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_IBM_POWER_SYSTEMS}`; +const GOOGLE_COMPUTE_ENGINE_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_GOOGLE_COMPUTE}`; +const AZURE_STACK_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_AZURE_STACK}`; +const AMAZON_EC2_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_AMAZON_EC2}`; +const IBM_POWERVC_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_IBM_POWERVC}`; +const IBM_CIC_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_IBM_CIC}`; +const OPENSTACK_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_OPENSTACK}`; +const TENANT_ID_VALUE = '101'; +const SUBSCRIPTION_ID_VALUE = 'z565815f-05b6-402f-1999-045155da7dq4'; +const ENDPOINT_URL_VALUE = '/api'; +const CLIENT_ID_VALUE = 'manageiq.example.com'; +const CLIENT_KEY_VALUE = 'test_client_key'; +const PORT_VALUE = '3000'; +const USERNAME_VALUE = 'admin@example.com'; +const PASSWORD_VALUE = 'password123'; +const PRIVATE_KEY_VALUE = + '-----BEGIN PRIVATE KEY-----\nMIIEvQIBAzApPugkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC\n-----END PRIVATE KEY-----'; +const PUBLIC_KEY_VALUE = + '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAz14iAAOCAQ8AMIIBCgKCAQEA\n-----END PUBLIC KEY-----'; +const CLOUD_API_KEY_VALUE = 'ibm_cloud_api_key_k#157'; +const GUID_VALUE = '723e4a67-e89b-1qd3-z486-920614074000'; +const PROJECT_ID_VALUE = 'gcp-project-123456'; +const ASSUME_ROLE_VALUE = 'arn:aws:iam::123456789012:role/ManageIQRole'; +const ACCESS_KEY_ID_VALUE = 'AKIAIOSFODNN7EXAMPLE'; +const SECRET_ACCESS_KEY_VALUE = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'; +const DOMAIN_ID_DEFAULT_VALUE = 'default'; +const PROVIDER_REGION_VALUE = 'RegionOne'; + +// Flash message text snippets +const FLASH_MESSAGE_OPERATION_CANCELLED = 'cancelled'; +const FLASH_MESSAGE_OPERATION_SAVED = 'saved'; +const FLASH_MESSAGE_DELETE_OPERATION = 'delete'; +const REFRESH_OPERATION_MESSAGE = 'Refresh'; +const REMOVE_PROVIDER_BROWSER_ALERT_MESSAGE = 'removed'; + +// Other message snippets +const VALIDATION_FAILED_COMMON_ERROR = 'Validation failed'; +const VALIDATION_SUCCESSFUL_COMMON_MESSAGE = 'Validation successful'; +const IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_VALIDATION_ERROR = + 'IAM authentication failed'; +const VMWARE_VCLOUD_VALIDATION_ERROR = + 'Socket error: no address for example.manageiq.com'; +const ORACLE_CLOUD_VALIDATION_ERROR = 'The format of tenancy is invalid.'; +const IBM_CLOUD_VPC_VALIDATION_ERROR = 'Provided API key could not be found.'; +const GOOGLE_COMPUTE_ENGINE_VALIDATION_ERROR = 'Invalid Google JSON key'; +const AZURE_STACK_VALIDATION_ERROR = + 'Failed to open TCP connection to example.manageiq.com:3000'; +const AZURE_VALIDATION_ERROR = + 'Incorrect credentials - no host component for URI'; +const AMAZON_EC2_VALIDATION_ERROR = + 'The security token included in the request is invalid.'; +const IBM_POWERVC_VALIDATION_ERROR = + 'unable to retrieve IBM PowerVC release version number'; +const IBM_CIC_VALIDATION_ERROR = 'Login attempt timed out'; +const OPENSTACK_VALIDATION_ERROR = + 'Socket error: no address for example.manageiq.com'; +const NAME_ALRADY_EXISTS_ERROR = 'already exists'; + +// Methods for VMware vCloud +function validateVmwareVcloudFormFields(isEdit) { + cy.getFormLabelByForAttribute({ forValue: 'type' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + if (isEdit) { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.disabled') + .find('option:selected') + .should('have.text', PROVIDER_TYPE_VMWARE_VCLOUD); + } else { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.enabled') + .select(PROVIDER_TYPE_VMWARE_VCLOUD); + } + cy.getFormLabelByForAttribute({ forValue: 'name' }) + .should('be.visible') + .and('contain.text', NAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) + .should('be.visible') + .and('contain.text', ZONE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'zone_id' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'api_version' }) + .should('be.visible') + .and('contain.text', API_VERSION_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'api_version' }) + .should('be.visible') + .and('be.enabled'); + cy.contains('h3', 'Endpoints').should('be.visible'); + /* Verify Default tab fields */ + cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.hostname' }) + .should('be.visible') + .and('contain.text', HOSTNAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.hostname' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.port' }) + .should('be.visible') + .and('contain.text', API_PORT_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.port', + inputType: 'number', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.userid', + }) + .should('be.visible') + .and('contain.text', USERNAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }) + .should('be.visible') + .and('be.enabled'); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', PASSWORD_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.password', + }) + .scrollIntoView() + .should('be.visible') + .and('contain.text', PASSWORD_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password-password-placeholder', + inputType: 'password', + }) + .scrollIntoView() + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + } + cy.contains('#default-tab__panel button', 'Validate') + .should('be.visible') + .and('be.disabled'); + cy.tabs({ tabLabel: EVENTS_TAB_LABEL }); + cy.getFormLabelByForAttribute({ forValue: 'event_stream_selection' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'event_stream_selection' }) + .should('be.visible') + .and('be.enabled') + .select(EVENT_STREAM_TYPE_AMQP); + cy.getFormLabelByForAttribute({ + forValue: 'endpoints.amqp.security_protocol', + }) + .should('be.visible') + .and('contain.text', SECURITY_PROTOCOL_FIELD_LABEL); + cy.getFormSelectFieldById({ + selectId: 'endpoints.amqp.security_protocol', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.amqp.hostname' }) + .should('be.visible') + .and('contain.text', HOSTNAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.amqp.hostname' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.amqp.port' }) + .scrollIntoView() + .should('be.visible') + .and('contain.text', API_PORT_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.amqp.port', + inputType: 'number', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'authentications.amqp.userid' }) + .should('be.visible') + .and('contain.text', USERNAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.amqp.userid', + }) + .should('be.visible') + .and('be.enabled'); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', PASSWORD_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.amqp.password', + }) + .should('be.visible') + .and('contain.text', PASSWORD_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.amqp.password-password-placeholder', + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.amqp.password', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + } + cy.contains('#events-tab__panel button', 'Validate') + .should('be.visible') + .and('be.disabled'); + cy.getFormFooterButtonByTypeWithText({ + buttonText: isEdit ? 'Save' : 'Add', + buttonType: 'submit', + }) + .should('be.visible') + .and('be.disabled'); + if (isEdit) { + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.visible') + .and('be.enabled'); + } + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) + .should('be.visible') + .and('be.enabled'); +} + +function fillVmwareVcloudForm({ nameValue, hostValue }) { + cy.getFormSelectFieldById({ selectId: 'type' }).select( + PROVIDER_TYPE_VMWARE_VCLOUD + ); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); + cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( + ZONE_OPTION_DEFAULT + ); + cy.getFormSelectFieldById({ selectId: 'api_version' }).select( + API_VERSION_TYPE_V5 + ); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.hostname', + }).type(hostValue); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.port', + inputType: 'number', + }) + .clear() + .type(PORT_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }).type(USERNAME_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password', + inputType: 'password', + }).type(PASSWORD_VALUE); +} + +function addVmwareVcloudProviderAndOpenEditForm({ nameValue, hostValue }) { + fillVmwareVcloudForm({ + nameValue, + hostValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + selectCreatedProvider(nameValue); + cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); +} + +// Methods for Oracle Cloud +function validateOracleCloudFormFields(isEdit) { + cy.getFormLabelByForAttribute({ forValue: 'type' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + if (isEdit) { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.disabled') + .find('option:selected') + .should('have.text', PROVIDER_TYPE_ORACLE_CLOUD); + } else { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.enabled') + .select(PROVIDER_TYPE_ORACLE_CLOUD); + } + cy.getFormLabelByForAttribute({ forValue: 'name' }) + .should('be.visible') + .and('contain.text', NAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) + .should('be.visible') + .and('contain.text', ZONE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'zone_id' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'provider_region' }) + .should('be.visible') + .and('contain.text', REGION_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'provider_region' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'uid_ems' }) + .should('be.visible') + .and('contain.text', TENANT_ID_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }) + .should('be.visible') + .and('be.enabled'); + cy.contains('h3', 'Endpoints').should('be.visible'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.userid', + }) + .should('be.visible') + .and('contain.text', USER_ID_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }) + .should('be.visible') + .and('be.enabled'); + cy.get('[id="authentications.default.userid-helper-text"]').contains( + 'privileged access' + ); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', PRIVATE_KEY_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.auth_key', + }) + .should('be.visible') + .and('contain.text', PRIVATE_KEY_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.auth_key-password-placeholder', + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormTextareaById({ textareaId: 'authentications.default.auth_key' }) + .should('be.visible') + .and('be.enabled'); + } + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.public_key', + }) + .scrollIntoView() + .should('be.visible') + .and('contain.text', PUBLIC_KEY_FIELD_LABEL); + cy.getFormTextareaById({ + textareaId: 'authentications.default.public_key', + }) + .should('be.visible') + .and('be.enabled'); + cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); + cy.getFormFooterButtonByTypeWithText({ + buttonText: isEdit ? 'Save' : 'Add', + buttonType: 'submit', + }) + .should('be.visible') + .and('be.disabled'); + if (isEdit) { + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.visible') + .and('be.disabled'); + } + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) + .should('be.visible') + .and('be.enabled'); +} + +function fillOracleCloudForm({ nameValue }) { + cy.getFormSelectFieldById({ selectId: 'type' }).select( + PROVIDER_TYPE_ORACLE_CLOUD + ); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); + cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( + ZONE_OPTION_DEFAULT + ); + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTION_HYDERABAD + ); + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type(TENANT_ID_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }).type(USERNAME_VALUE); + cy.getFormTextareaById({ + textareaId: 'authentications.default.auth_key', + }).type(PRIVATE_KEY_VALUE); + cy.getFormTextareaById({ + textareaId: 'authentications.default.public_key', + }).type(PUBLIC_KEY_VALUE); +} + +function addOracleCloudProviderAndOpenEditForm({ nameValue }) { + fillOracleCloudForm({ + nameValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + selectCreatedProvider(nameValue); + cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); +} + +// Methods for IBM Cloud VPC +function validateIbmCloudVpcFormFields(isEdit) { + cy.getFormLabelByForAttribute({ forValue: 'type' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + if (isEdit) { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.disabled') + .find('option:selected') + .should('have.text', PROVIDER_TYPE_IBM_CLOUD_VPC); + } else { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.enabled') + .select(PROVIDER_TYPE_IBM_CLOUD_VPC); + } + cy.getFormLabelByForAttribute({ forValue: 'name' }) + .should('be.visible') + .and('contain.text', NAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) + .should('be.visible') + .and('contain.text', ZONE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'zone_id' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'provider_region' }) + .should('be.visible') + .and('contain.text', REGION_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'provider_region' }) + .should('be.visible') + .and('be.enabled'); + cy.contains('h3', 'Endpoint').should('be.visible'); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', IBM_CLOUD_COMMON_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.auth_key', + }) + .should('be.visible') + .and('contain.text', IBM_CLOUD_COMMON_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.auth_key-password-placeholder', + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.auth_key', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + } + cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); + cy.tabs({ tabLabel: METRICS_TAB_LABEL }); + cy.getFormLabelByForAttribute({ forValue: 'metrics_selection' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'metrics_selection' }) + .should('be.visible') + .and('be.enabled') + .select(ENABLED_SELECT_OPTION); + cy.getFormLabelByForAttribute({ + forValue: 'endpoints.metrics.options.monitoring_instance_id', + }) + .should('be.visible') + .and('contain.text', IBM_CLOUD_COMMON_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.metrics.options.monitoring_instance_id', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + cy.tabs({ tabLabel: EVENTS_TAB_LABEL }); + cy.getFormLabelByForAttribute({ forValue: 'events_selection' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'events_selection' }) + .should('be.visible') + .and('be.enabled') + .select(ENABLED_SELECT_OPTION); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.events.auth_key', + }) + .should('be.visible') + .and('contain.text', IBM_CLOUD_COMMON_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.events.auth_key', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + if (isEdit) { + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Save', + buttonType: 'submit', + }) + .should('be.visible') + .and('be.enabled'); + } else { + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .should('be.visible') + .and('be.disabled'); + } + if (isEdit) { + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.visible') + .and('be.enabled'); + } + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) + .should('be.visible') + .and('be.enabled'); +} + +function fillIbmCloudVpcForm({ nameValue }) { + cy.getFormSelectFieldById({ selectId: 'type' }).select( + PROVIDER_TYPE_IBM_CLOUD_VPC + ); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); + cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( + ZONE_OPTION_DEFAULT + ); + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTION_AUSTRALIA + ); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.auth_key', + inputType: 'password', + }).type(CLOUD_API_KEY_VALUE); +} + +function addIbmCloudVpcProviderAndOpenEditForm({ nameValue }) { + fillIbmCloudVpcForm({ + nameValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + selectCreatedProvider(nameValue); + cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); +} + +// Methods for IBM Power Systems Virtual Servers +function validateIbmPowerSystemsVirtualServersFormFields(isEdit) { + cy.getFormLabelByForAttribute({ forValue: 'type' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + if (isEdit) { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.disabled') + .find('option:selected') + .should('have.text', PROVIDER_TYPE_IBM_POWER_SYSTEMS); + } else { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.enabled') + .select(PROVIDER_TYPE_IBM_POWER_SYSTEMS); + } + cy.getFormLabelByForAttribute({ forValue: 'name' }) + .should('be.visible') + .and('contain.text', NAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) + .should('be.visible') + .and('contain.text', ZONE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'zone_id' }) + .should('be.visible') + .and('be.enabled'); + cy.contains('h3', 'Endpoints').should('be.visible'); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', IBM_CLOUD_COMMON_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.auth_key', + }) + .should('be.visible') + .and('contain.text', IBM_CLOUD_COMMON_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.auth_key-password-placeholder', + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.auth_key', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + } + cy.getFormLabelByForAttribute({ forValue: 'uid_ems' }) + .should('be.visible') + .and('contain.text', SERVICE_COMMON_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }) + .should('be.visible') + .and('be.enabled'); + cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); + cy.getFormFooterButtonByTypeWithText({ + buttonText: isEdit ? 'Save' : 'Add', + buttonType: 'submit', + }) + .scrollIntoView() + .should('be.visible') + .and('be.disabled'); + if (isEdit) { + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.visible') + .and('be.disabled'); + } + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) + .should('be.visible') + .and('be.enabled'); +} + +function fillIbmPowerSystemsVirtualServersForm({ nameValue }) { + cy.getFormSelectFieldById({ selectId: 'type' }).select( + PROVIDER_TYPE_IBM_POWER_SYSTEMS + ); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); + cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( + ZONE_OPTION_DEFAULT + ); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.auth_key', + inputType: 'password', + }).type(CLOUD_API_KEY_VALUE); + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type(GUID_VALUE); +} + +function addIbmPowerSystemsVirtualServersProviderAndOpenEditForm({ + nameValue, +}) { + fillIbmPowerSystemsVirtualServersForm({ + nameValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + selectCreatedProvider(nameValue); + cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); +} + +// Methods for Google Compute Engine +function validateGoogleComputeEngineFormFields(isEdit) { + cy.getFormLabelByForAttribute({ forValue: 'type' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + if (isEdit) { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.disabled') + .find('option:selected') + .should('have.text', PROVIDER_TYPE_GOOGLE_COMPUTE); + } else { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.enabled') + .select(PROVIDER_TYPE_GOOGLE_COMPUTE); + } + cy.getFormLabelByForAttribute({ forValue: 'name' }) + .should('be.visible') + .and('contain.text', NAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) + .should('be.visible') + .and('contain.text', ZONE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'zone_id' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'project' }) + .should('be.visible') + .and('contain.text', PROJECT_ID_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'project' }) + .should('be.visible') + .and('be.enabled'); + cy.contains('h3', 'Endpoint').should('be.visible'); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', SERVICE_COMMON_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.auth_key', + }) + .should('be.visible') + .and('contain.text', SERVICE_COMMON_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.auth_key-password-placeholder', + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormTextareaById({ textareaId: 'authentications.default.auth_key' }) + .should('be.visible') + .and('be.enabled'); + } + cy.contains('button', 'Validate') + .scrollIntoView() + .should('be.visible') + .and('be.disabled'); + cy.getFormFooterButtonByTypeWithText({ + buttonText: isEdit ? 'Save' : 'Add', + buttonType: 'submit', + }) + .should('be.visible') + .and('be.disabled'); + if (isEdit) { + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.visible') + .and('be.disabled'); + } + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) + .should('be.visible') + .and('be.enabled'); +} + +function fillGoogleComputeEngineForm({ nameValue }) { + cy.getFormSelectFieldById({ selectId: 'type' }).select( + PROVIDER_TYPE_GOOGLE_COMPUTE + ); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); + cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( + ZONE_OPTION_DEFAULT + ); + cy.getFormInputFieldByIdAndType({ inputId: 'project' }).type( + PROJECT_ID_VALUE + ); + cy.getFormTextareaById({ + textareaId: 'authentications.default.auth_key', + }).type( + `{"type":"service_account","project_id":"${PROJECT_ID_VALUE}","private_key":"${PRIVATE_KEY_VALUE}"}` + ); +} + +function addGoogleComputeEngineProviderAndOpenEditForm({ nameValue }) { + fillGoogleComputeEngineForm({ + nameValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + selectCreatedProvider(nameValue); + cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); +} + +// Methods for Azure Stack +function validateAzureStackFormFields(isEdit) { + cy.getFormLabelByForAttribute({ forValue: 'type' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + if (isEdit) { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.disabled') + .find('option:selected') + .should('have.text', PROVIDER_TYPE_AZURE_STACK); + } else { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.enabled') + .select(PROVIDER_TYPE_AZURE_STACK); + } + cy.getFormLabelByForAttribute({ forValue: 'name' }) + .should('be.visible') + .and('contain.text', NAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) + .should('be.visible') + .and('contain.text', ZONE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'zone_id' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'uid_ems' }) + .should('be.visible') + .and('contain.text', TENANT_ID_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'subscription' }) + .should('be.visible') + .and('contain.text', SUBSCRIPTION_ID_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'subscription' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'api_version' }) + .should('be.visible') + .and('contain.text', API_VERSION_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'api_version' }) + .should('be.visible') + .and('be.enabled'); + cy.contains('h3', 'Endpoint').should('be.visible'); + cy.getFormLabelByForAttribute({ + forValue: 'endpoints.default.security_protocol', + }) + .should('be.visible') + .and('contain.text', SECURITY_PROTOCOL_FIELD_LABEL); + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.hostname' }) + .should('be.visible') + .and('contain.text', HOSTNAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.hostname' }) + .scrollIntoView() + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.port' }) + .should('be.visible') + .and('contain.text', API_PORT_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.port', + inputType: 'number', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.userid', + }) + .should('be.visible') + .and('contain.text', USERNAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }) + .should('be.visible') + .and('be.enabled'); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', PASSWORD_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.password', + }) + .should('be.visible') + .and('contain.text', PASSWORD_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password-password-placeholder', + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + } + cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); + cy.getFormFooterButtonByTypeWithText({ + buttonText: isEdit ? 'Save' : 'Add', + buttonType: 'submit', + }) + .should('be.visible') + .and('be.disabled'); + if (isEdit) { + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.visible') + .and('be.disabled'); + } + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) + .should('be.visible') + .and('be.enabled'); +} + +function fillAzureStackForm({ nameValue, hostValue }) { + cy.getFormSelectFieldById({ selectId: 'type' }).select( + PROVIDER_TYPE_AZURE_STACK + ); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); + cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( + ZONE_OPTION_DEFAULT + ); + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type(TENANT_ID_VALUE); + cy.getFormInputFieldByIdAndType({ inputId: 'subscription' }).type( + SUBSCRIPTION_ID_VALUE + ); + cy.getFormSelectFieldById({ selectId: 'api_version' }).select( + API_VERSION_TYPE_2017 + ); + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }).select(SECURITY_PROTOCOL_SSL); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.hostname', + }).type(hostValue); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.port', + inputType: 'number', + }).type(PORT_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }).type(USERNAME_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password', + inputType: 'password', + }).type(PASSWORD_VALUE); +} + +function addAzureStackProviderAndOpenEditForm({ nameValue, hostValue }) { + fillAzureStackForm({ + nameValue, + hostValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.interceptApi({ + alias: 'addAzureStackProviderApi', + urlPattern: '/api/providers', + triggerFn: () => + cy + .getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .click(), + responseInterceptor: (req) => { + // Let the request go through to the server and then override the response statusCode + // to 200, server will return internal_server_error(500) since we are using mock values + // for fields like host, port, etc. + req.continue((res) => { + res.send(200); + }); + }, + }); + selectCreatedProvider(nameValue); + // TODO: Switch to cy.interceptApi once its enhanced to support multiple api intercepts from a single event + cy.intercept( + 'GET', + /\/api\/providers\/(\d+)\?attributes=endpoints,authentications/, + (req) => { + const providerId = req.url.match(/\/api\/providers\/(\d+)\?/)[1]; + // Let the request go through to the server and then override the response statusCode to 200 and override the + // response body with the form input values, as these will be used to populate edit form in the UI. The "type" + // field value from the response will be used to hit to OPTIONS - /api/providers?type API - + // (like /api/providers?type=ManageIQ::Providers::AzureStack::CloudManager). + // If not overridden, server will return internal_server_error(500) since we are using mock values for + // fields like host, port, etc. + req.continue((res) => { + res.send(200, { + id: providerId, + type: 'ManageIQ::Providers::AzureStack::CloudManager', + name: nameValue, + zone_id: '2', + uid_ems: TENANT_ID_VALUE, + subscription: SUBSCRIPTION_ID_VALUE, + api_version: API_VERSION_TYPE_2017, + endpoints: [ + { + role: 'default', // role is required to populate host & port + hostname: hostValue, + port: PORT_VALUE, + security_protocol: 'ssl-with-validation', + }, + ], + authentications: [ + { + authtype: 'default', // authtype is required to populate host & port + userid: USERNAME_VALUE, + }, + ], + }); + }); + } + ).as('getProviderFieldValuesApi'); + // TODO: Switch to cy.interceptApi once its enhanced to support multiple api intercepts from a single event + cy.intercept( + 'GET', + '/api/zones?expand=resources&attributes=id,name,visible&filter[]=visible!=false&sort_by=name', // allow to hit server + (req) => { + req.continue((res) => { + res.send(200, { + name: 'zones', + count: 2, + subcount: 1, + subquery_count: 1, + pages: 1, + resources: [ + { + href: 'http://localhost:3000/api/zones/2', + id: '2', + name: ZONE_OPTION_DEFAULT, + visible: true, + }, + ], + }); + }); + } + ).as('getZoneDropdownOptionsApi'); + cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); + cy.wait('@getProviderFieldValuesApi'); + cy.wait('@getZoneDropdownOptionsApi'); +} + +// Methods for Azure +function validateAzureFormFields(isEdit) { + cy.getFormLabelByForAttribute({ forValue: 'type' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + if (isEdit) { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.disabled') + .find('option:selected') + .should('have.text', PROVIDER_TYPE_AZURE); + } else { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.enabled') + .select(PROVIDER_TYPE_AZURE); + } + cy.getFormLabelByForAttribute({ forValue: 'name' }) + .should('be.visible') + .and('contain.text', NAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) + .should('be.visible') + .and('contain.text', ZONE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'zone_id' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'provider_region' }) + .should('be.visible') + .and('contain.text', REGION_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'provider_region' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'uid_ems' }) + .should('be.visible') + .and('contain.text', TENANT_ID_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'subscription' }) + .should('be.visible') + .and('contain.text', SUBSCRIPTION_ID_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'subscription' }) + .should('be.visible') + .and('be.enabled'); + cy.contains('h3', 'Endpoint').should('be.visible'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.url' }) + .should('be.visible') + .and('contain.text', ENDPOINT_URL_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.url' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.userid', + }) + .should('be.visible') + .and('contain.text', CLIENT_ID_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }) + .scrollIntoView() + .should('be.visible') + .and('be.enabled'); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', CLIENT_KEY_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.password', + }) + .should('be.visible') + .and('contain.text', CLIENT_KEY_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password-password-placeholder', + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + } + cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); + cy.getFormFooterButtonByTypeWithText({ + buttonText: isEdit ? 'Save' : 'Add', + buttonType: 'submit', + }) + .should('be.visible') + .and('be.disabled'); + if (isEdit) { + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.visible') + .and('be.disabled'); + } + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) + .should('be.visible') + .and('be.enabled'); +} + +function fillAzureForm({ nameValue }) { + cy.getFormSelectFieldById({ selectId: 'type' }).select(PROVIDER_TYPE_AZURE); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); + cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( + ZONE_OPTION_DEFAULT + ); + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTION_CENTRAL_INDIA + ); + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type(TENANT_ID_VALUE); + cy.getFormInputFieldByIdAndType({ inputId: 'subscription' }).type( + SUBSCRIPTION_ID_VALUE + ); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.url', + }).type(ENDPOINT_URL_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }).type(CLIENT_ID_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password', + inputType: 'password', + }).type(CLIENT_KEY_VALUE); +} + +function addAzureProviderAndOpenEditForm({ nameValue }) { + fillAzureForm({ + nameValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + selectCreatedProvider(nameValue); + cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); +} + +// Methods for Amazon EC2 +function validateAmazonEC2FormFields(isEdit) { + cy.getFormLabelByForAttribute({ forValue: 'type' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + if (isEdit) { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.disabled') + .find('option:selected') + .should('have.text', PROVIDER_TYPE_AMAZON_EC2); + } else { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.enabled') + .select(PROVIDER_TYPE_AMAZON_EC2); + } + cy.getFormLabelByForAttribute({ forValue: 'name' }) + .should('be.visible') + .and('contain.text', NAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) + .should('be.visible') + .and('contain.text', ZONE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'zone_id' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'provider_region' }) + .should('be.visible') + .and('contain.text', REGION_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'provider_region' }) + .should('be.visible') + .and('be.enabled'); + cy.contains('h3', 'Endpoints').should('be.visible'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.url' }) + .should('be.visible') + .and('contain.text', ENDPOINT_URL_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.url' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.service_account', + }) + .should('be.visible') + .and('contain.text', ASSUME_ROLE_ARN_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.service_account', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.userid', + }) + .should('be.visible') + .and('contain.text', ACCESS_KEY_ID_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }) + .should('be.visible') + .and('be.enabled'); + if (isEdit) { + cy.contains( + '.bx--fieldset legend.bx--label', + SECRET_ACCESS_KEY_FIELD_LABEL + ); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.password', + }) + .scrollIntoView() + .should('be.visible') + .and('contain.text', SECRET_ACCESS_KEY_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password-password-placeholder', + inputType: 'password', + }) + .scrollIntoView() + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + } + cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); + cy.tabs({ tabLabel: SMARTSTATE_DOCKER_TAB_LABEL }); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.smartstate_docker.userid', + }) + .should('be.visible') + .and('contain.text', USERNAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.smartstate_docker.userid', + }) + .should('be.visible') + .and('be.enabled'); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', PASSWORD_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.smartstate_docker.password', + }) + .should('be.visible') + .and('contain.text', PASSWORD_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: + 'authentications.smartstate_docker.password-password-placeholder', + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.smartstate_docker.password', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + } + cy.getFormFooterButtonByTypeWithText({ + buttonText: isEdit ? 'Save' : 'Add', + buttonType: 'submit', + }) + .should('be.visible') + .and('be.disabled'); + if (isEdit) { + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.visible') + .and('be.disabled'); + } + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) + .should('be.visible') + .and('be.enabled'); +} + +function fillAmazonEC2Form({ nameValue }) { + cy.getFormSelectFieldById({ selectId: 'type' }).select( + PROVIDER_TYPE_AMAZON_EC2 + ); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); + cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( + ZONE_OPTION_DEFAULT + ); + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTION_CANADA + ); + cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.url' }).type( + ENDPOINT_URL_VALUE + ); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.service_account', + }).type(ASSUME_ROLE_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }).type(ACCESS_KEY_ID_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password', + inputType: 'password', + }).type(SECRET_ACCESS_KEY_VALUE); +} + +function addAmazonEC2ProviderAndOpenEditForm({ nameValue }) { + fillAmazonEC2Form({ + nameValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + selectCreatedProvider(nameValue); + cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); +} + +// Methods for IBM PowerVC +function validateIbmPowerVcFormFields(isEdit) { + cy.getFormLabelByForAttribute({ forValue: 'type' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + if (isEdit) { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.disabled') + .find('option:selected') + .should('have.text', PROVIDER_TYPE_IBM_POWERVC); + } else { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.enabled') + .select(PROVIDER_TYPE_IBM_POWERVC); + } + cy.getFormLabelByForAttribute({ forValue: 'name' }) + .should('be.visible') + .and('contain.text', NAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) + .should('be.visible') + .and('contain.text', ZONE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'zone_id' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'provider_region' }) + .should('be.visible') + .and('contain.text', PROVIDER_REGION_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'provider_region' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'tenant_mapping_enabled' }) + .should('be.visible') + .and('contain.text', TENANT_MAPPING_ENABLED_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'tenant_mapping_enabled', + inputType: 'checkbox', + }) + .should('be.visible') + .and('be.enabled'); + cy.contains('h3', 'Endpoints').should('be.visible'); + cy.getFormLabelByForAttribute({ + forValue: 'endpoints.default.security_protocol', + }) + .should('be.visible') + .and('contain.text', SECURITY_PROTOCOL_FIELD_LABEL); + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.hostname' }) + .scrollIntoView() + .should('be.visible') + .and('contain.text', POWERVC_API_ENDPOINT_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.hostname' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.port' }) + .should('be.visible') + .and('contain.text', API_PORT_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.port', + inputType: 'number', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.userid', + }) + .should('be.visible') + .and('contain.text', API_USERNAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }) + .should('be.visible') + .and('be.enabled'); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', API_PASSWORD_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.password', + }) + .should('be.visible') + .and('contain.text', API_PASSWORD_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password-password-placeholder', + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + } + cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); + cy.tabs({ tabLabel: EVENTS_TAB_LABEL }); + cy.getFormLabelByForAttribute({ forValue: 'event_stream_selection' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'event_stream_selection' }) + .should('be.visible') + .and('be.enabled'); + cy.tabs({ tabLabel: RSA_KEY_PAIR_TAB_LABEL }); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.ssh_keypair.userid', + }) + .should('be.visible') + .and('contain.text', USERNAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.ssh_keypair.userid', + }) + .should('be.visible') + .and('be.enabled'); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', PRIVATE_KEY_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.ssh_keypair.auth_key', + }) + .should('be.visible') + .and('contain.text', PRIVATE_KEY_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.ssh_keypair.auth_key-password-placeholder', + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormTextareaById({ + textareaId: 'authentications.ssh_keypair.auth_key', + }) + .should('be.visible') + .and('be.enabled'); + } + cy.tabs({ tabLabel: IMAGE_EXPORT_TAB_LABEL }); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.node.userid', + }) + .should('be.visible') + .and('contain.text', POWERVC_COMMON_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.node.userid', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.node.options', + }) + .should('be.visible') + .and('contain.text', ANSIBLE_ACCESS_METHOD_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'authentications.node.options' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.node.auth_key_password', + }) + .should('be.visible') + .and('contain.text', POWERVC_COMMON_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.node.auth_key_password', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.node.auth_key', + }) + .should('be.visible') + .and('contain.text', POWERVC_COMMON_FIELD_LABEL); + cy.getFormTextareaById({ + textareaId: 'authentications.node.auth_key', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormFooterButtonByTypeWithText({ + buttonText: isEdit ? 'Save' : 'Add', + buttonType: 'submit', + }) + .scrollIntoView() + .should('be.visible') + .and('be.disabled'); + if (isEdit) { + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.visible') + .and('be.disabled'); + } + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) + .should('be.visible') + .and('be.enabled'); +} + +function fillIbmPowerVcForm({ nameValue, hostValue }) { + cy.getFormSelectFieldById({ selectId: 'type' }).select( + PROVIDER_TYPE_IBM_POWERVC + ); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); + cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( + ZONE_OPTION_DEFAULT + ); + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }) + .clear() + .type(DOMAIN_ID_DEFAULT_VALUE); + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }).select(SECURITY_PROTOCOL_SSL); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.hostname', + }).type(hostValue); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.port', + inputType: 'number', + }) + .clear() + .type(PORT_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }).type(USERNAME_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password', + inputType: 'password', + }).type(PASSWORD_VALUE); +} + +function addIbmPowerVcProviderAndOpenEditForm({ nameValue, hostValue }) { + fillIbmPowerVcForm({ + nameValue, + hostValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + selectCreatedProvider(nameValue); + cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); +} + +// Methods for IBM Cloud Infrastructure Center +function validateIbmCloudInfrastructureCenterFormFields(isEdit) { + cy.getFormLabelByForAttribute({ forValue: 'type' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + if (isEdit) { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.disabled') + .find('option:selected') + .should('have.text', PROVIDER_TYPE_IBM_CIC); + } else { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.enabled') + .select(PROVIDER_TYPE_IBM_CIC); + } + cy.getFormLabelByForAttribute({ forValue: 'name' }) + .should('be.visible') + .and('contain.text', NAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) + .should('be.visible') + .and('contain.text', ZONE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'zone_id' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'provider_region' }) + .should('be.visible') + .and('contain.text', PROVIDER_REGION_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'provider_region' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'api_version' }) + .should('be.visible') + .and('contain.text', API_VERSION_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'api_version' }) + .should('be.visible') + .and('be.enabled') + .select(API_VERSION_TYPE_V3); + cy.getFormLabelByForAttribute({ forValue: 'uid_ems' }) + .should('be.visible') + .and('contain.text', DOMAIN_ID_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'tenant_mapping_enabled' }) + .should('be.visible') + .and('contain.text', TENANT_MAPPING_ENABLED_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'tenant_mapping_enabled', + inputType: 'checkbox', + }) + .should('be.visible') + .and('be.enabled'); + cy.contains('h3', 'Endpoints').should('be.visible'); + cy.contains('h3', 'Default').should('be.visible'); + cy.getFormLabelByForAttribute({ + forValue: 'endpoints.default.security_protocol', + }) + .should('be.visible') + .and('contain.text', SECURITY_PROTOCOL_FIELD_LABEL); + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'endpoints.default.hostname', + }).should('be.visible'); + cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.hostname' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.port' }) + .should('be.visible') + .and('contain.text', API_PORT_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.port', + inputType: 'number', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.userid', + }).should('be.visible'); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }) + .should('be.visible') + .and('be.enabled'); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', PASSWORD_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.password', + }) + .should('be.visible') + .and('contain.text', PASSWORD_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password-password-placeholder', + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + } + cy.contains('h3', 'Events').scrollIntoView().should('be.visible'); + cy.getFormLabelByForAttribute({ forValue: 'event_stream_selection' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'event_stream_selection' }) + .should('be.visible') + .and('be.enabled') + .select(EVENT_STREAM_TYPE_STF); + cy.getFormLabelByForAttribute({ + forValue: 'endpoints.stf.security_protocol', + }) + .should('be.visible') + .and('contain.text', SECURITY_PROTOCOL_FIELD_LABEL); + cy.getFormSelectFieldById({ + selectId: 'endpoints.stf.security_protocol', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'endpoints.stf.hostname', + }).should('be.visible'); + cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.stf.hostname' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.stf.port' }) + .should('be.visible') + .and('contain.text', API_PORT_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.stf.port', + inputType: 'number', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormSelectFieldById({ selectId: 'event_stream_selection' }).select( + EVENT_STREAM_TYPE_AMQP + ); + cy.getFormLabelByForAttribute({ + forValue: 'endpoints.amqp.hostname', + }).should('be.visible'); + cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.amqp.hostname' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.amqp.port' }) + .should('be.visible') + .and('contain.text', API_PORT_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.amqp.port', + inputType: 'number', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.amqp.userid', + }) + .should('be.visible') + .and('contain.text', USERNAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.amqp.userid', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.amqp.password', + }) + .should('be.visible') + .and('contain.text', PASSWORD_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.amqp.password', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.ssh_keypair.userid', + }) + .should('be.visible') + .and('contain.text', USERNAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.ssh_keypair.userid', + }) + .should('be.visible') + .and('be.enabled'); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', PRIVATE_KEY_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.ssh_keypair.auth_key', + }) + .should('be.visible') + .and('contain.text', PRIVATE_KEY_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.ssh_keypair.auth_key-password-placeholder', + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormTextareaById({ + textareaId: 'authentications.ssh_keypair.auth_key', + }) + .should('be.visible') + .and('be.enabled'); + } + cy.getFormFooterButtonByTypeWithText({ + buttonText: isEdit ? 'Save' : 'Add', + buttonType: 'submit', + }) + .scrollIntoView() + .should('be.visible') + .and('be.disabled'); + if (isEdit) { + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.visible') + .and('be.enabled'); + } + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) + .should('be.visible') + .and('be.enabled'); +} + +function fillIbmCloudInfrastructureCenterForm({ nameValue, hostValue }) { + cy.getFormSelectFieldById({ selectId: 'type' }).select(PROVIDER_TYPE_IBM_CIC); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); + cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( + ZONE_OPTION_DEFAULT + ); + cy.getFormInputFieldByIdAndType({ inputId: 'provider_region' }).type( + PROVIDER_REGION_VALUE + ); + cy.getFormSelectFieldById({ selectId: 'api_version' }).select( + API_VERSION_TYPE_V3 + ); + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type( + DOMAIN_ID_DEFAULT_VALUE + ); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.hostname', + }).type(hostValue); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.port', + inputType: 'number', + }) + .clear() + .type(PORT_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }).type(USERNAME_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password', + inputType: 'password', + }).type(PASSWORD_VALUE); +} + +function addIbmCloudInfrastructureCenterProviderAndOpenEditForm({ + nameValue, + hostValue, +}) { + fillIbmCloudInfrastructureCenterForm({ + nameValue, + hostValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + selectCreatedProvider(nameValue); + cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); +} + +// Methods for OpenStack +function validateOpenstackFormFields(isEdit) { + cy.getFormLabelByForAttribute({ forValue: 'type' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + if (isEdit) { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.disabled') + .find('option:selected') + .should('have.text', PROVIDER_TYPE_OPENSTACK); + } else { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.enabled') + .select(PROVIDER_TYPE_OPENSTACK); + } + cy.getFormLabelByForAttribute({ forValue: 'name' }) + .should('be.visible') + .and('contain.text', NAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) + .should('be.visible') + .and('contain.text', ZONE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'zone_id' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'provider_region' }) + .should('be.visible') + .and('contain.text', PROVIDER_REGION_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'provider_region' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'provider_id' }) + .should('be.visible') + .and('contain.text', OPENSTACK_INFRA_PROVIDER_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'provider_id' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'api_version' }) + .should('be.visible') + .and('contain.text', API_VERSION_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'api_version' }) + .should('be.visible') + .and('be.enabled') + .select(API_VERSION_TYPE_V3); + cy.getFormLabelByForAttribute({ forValue: 'uid_ems' }) + .should('be.visible') + .and('contain.text', DOMAIN_ID_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'tenant_mapping_enabled' }) + .should('be.visible') + .and('contain.text', TENANT_MAPPING_ENABLED_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'tenant_mapping_enabled', + inputType: 'checkbox', + }) + .should('be.visible') + .and('be.enabled'); + cy.contains('h3', 'Endpoints').should('be.visible'); + cy.contains('h3', 'Default').should('be.visible'); + cy.getFormLabelByForAttribute({ + forValue: 'endpoints.default.security_protocol', + }) + .should('be.visible') + .and('contain.text', SECURITY_PROTOCOL_FIELD_LABEL); + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'endpoints.default.hostname', + }).should('be.visible'); + cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.hostname' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.port' }) + .should('be.visible') + .and('contain.text', API_PORT_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.port', + inputType: 'number', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.userid', + }).should('be.visible'); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }) + .should('be.visible') + .and('be.enabled'); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', PASSWORD_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.default.password', + }) + .should('be.visible') + .and('contain.text', PASSWORD_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password-password-placeholder', + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + } + cy.contains('h3', 'Events').scrollIntoView().should('be.visible'); + cy.getFormLabelByForAttribute({ forValue: 'event_stream_selection' }) + .should('be.visible') + .and('contain.text', TYPE_FIELD_LABEL); + cy.getFormSelectFieldById({ selectId: 'event_stream_selection' }) + .should('be.visible') + .and('be.enabled') + .select(EVENT_STREAM_TYPE_STF); + cy.getFormLabelByForAttribute({ + forValue: 'endpoints.stf.security_protocol', + }) + .should('be.visible') + .and('contain.text', SECURITY_PROTOCOL_FIELD_LABEL); + cy.getFormSelectFieldById({ + selectId: 'endpoints.stf.security_protocol', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'endpoints.stf.hostname', + }).should('be.visible'); + cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.stf.hostname' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.stf.port' }) + .should('be.visible') + .and('contain.text', API_PORT_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.stf.port', + inputType: 'number', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormSelectFieldById({ selectId: 'event_stream_selection' }).select( + EVENT_STREAM_TYPE_AMQP + ); + cy.getFormLabelByForAttribute({ + forValue: 'endpoints.amqp.hostname', + }).should('be.visible'); + cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.amqp.hostname' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'endpoints.amqp.port' }) + .should('be.visible') + .and('contain.text', API_PORT_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.amqp.port', + inputType: 'number', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.amqp.userid', + }) + .should('be.visible') + .and('contain.text', USERNAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.amqp.userid', + }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.amqp.password', + }) + .should('be.visible') + .and('contain.text', PASSWORD_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.amqp.password', + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); + cy.getFormLabelByForAttribute({ + forValue: 'authentications.ssh_keypair.userid', + }) + .should('be.visible') + .and('contain.text', USERNAME_FIELD_LABEL); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.ssh_keypair.userid', + }) + .should('be.visible') + .and('be.enabled'); + if (isEdit) { + cy.contains('.bx--fieldset legend.bx--label', PRIVATE_KEY_FIELD_LABEL); + } else { + cy.getFormLabelByForAttribute({ + forValue: 'authentications.ssh_keypair.auth_key', + }) + .should('be.visible') + .and('contain.text', PRIVATE_KEY_FIELD_LABEL); + } + if (isEdit) { + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.ssh_keypair.auth_key-password-placeholder', + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormTextareaById({ + textareaId: 'authentications.ssh_keypair.auth_key', + }) + .should('be.visible') + .and('be.enabled'); + } + cy.getFormFooterButtonByTypeWithText({ + buttonText: isEdit ? 'Save' : 'Add', + buttonType: 'submit', + }) + .scrollIntoView() + .should('be.visible') + .and('be.disabled'); + if (isEdit) { + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.visible') + .and('be.enabled'); + } + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) + .should('be.visible') + .and('be.enabled'); +} + +function fillOpenstackForm({ nameValue, hostValue }) { + cy.getFormSelectFieldById({ selectId: 'type' }).select( + PROVIDER_TYPE_OPENSTACK + ); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); + cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( + ZONE_OPTION_DEFAULT + ); + cy.getFormInputFieldByIdAndType({ inputId: 'provider_region' }).type( + PROVIDER_REGION_VALUE + ); + cy.getFormSelectFieldById({ selectId: 'api_version' }).select( + API_VERSION_TYPE_V3 + ); + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type( + DOMAIN_ID_DEFAULT_VALUE + ); + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }).select(SECURITY_PROTOCOL_SSL); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.hostname', + }).type(hostValue); + cy.getFormInputFieldByIdAndType({ + inputId: 'endpoints.default.port', + inputType: 'number', + }) + .clear() + .type(PORT_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.userid', + }).type(USERNAME_VALUE); + cy.getFormInputFieldByIdAndType({ + inputId: 'authentications.default.password', + inputType: 'password', + }).type(PASSWORD_VALUE); +} + +function addOpenstackProviderAndOpenEditForm({ nameValue, hostValue }) { + fillOpenstackForm({ + nameValue, + hostValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + selectCreatedProvider(nameValue); + cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); +} + +// Other common methods +function selectCreatedProvider(providerName) { + // Set pagination to 200 items per page to include the target provider despite pending deletions + // The test will create up to 55 records in total + cy.get( + '.miq-fieldset-content .miq-pagination select#bx-pagination-select-1' + ).select('200'); + cy.get('.miq-data-table table tbody tr').each((row) => { + if ( + row.find('td').filter((_ind, el) => el.innerText.trim() === providerName) + .length + ) { + if (!row.hasClass('bx--data-table--selected')) { + cy.wrap(row) + .find('.bx--checkbox--inline label.bx--checkbox-label') + .click(); + } + // Exit loop + return false; + } + // Returning null to get rid of eslint warning, has no impact + return null; + }); +} + +function assertValidationFailureMessage() { + cy.contains( + '.ddorg__carbon-error-helper-text', + VALIDATION_FAILED_COMMON_ERROR + ); +} + +function assertValidationSuccessMessage() { + cy.contains('.bx--form__helper-text', VALIDATION_SUCCESSFUL_COMMON_MESSAGE); +} + +function assertNameAlreadyExistsError() { + cy.contains('#name-error-msg', NAME_ALRADY_EXISTS_ERROR); +} + +function validate({ stubErrorResponse, errorMessage }) { + let response = { state: 'Finished', status: 'Error' }; + if (stubErrorResponse) { + response = { + ...response, + message: errorMessage, + }; + } else { + response = { ...response, status: 'Ok', task_results: {} }; + } + // not using cy.interceptApi because each validate call requires a fresh alias registration + // reusing the same intercept callback results in it returning the first response object + cy.intercept('GET', '/api/tasks/*?attributes=task_results', response).as( + 'validateApi' + ); + cy.contains('button', 'Validate').click(); + cy.wait('@validateApi'); +} + +function selectProviderAndDeleteWithOptionalFlashMessageCheck({ + createdProviderName, + assertDeleteFlashMessage, +}) { + selectCreatedProvider(createdProviderName); + cy.interceptApi({ + alias: 'deleteProviderApi', + urlPattern: '/ems_cloud/button?pressed=ems_cloud_delete', + triggerFn: () => + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => + cy.toolbar(CONFIG_TOOLBAR_BUTTON, REMOVE_PROVIDER_CONFIG_OPTION), + containsText: REMOVE_PROVIDER_BROWSER_ALERT_MESSAGE, + }), + onApiResponse: () => { + if (assertDeleteFlashMessage) { + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_DELETE_OPERATION); + } + }, + }); +} + +function cleanUp({ createdProviderName }) { + cy.url() + .then((url) => { + // Navigate to cloud providers table view + if (!url.endsWith(CLOUD_PROVIDERS_LIST_URL)) { + cy.visit(CLOUD_PROVIDERS_LIST_URL); + } + }) + .then(() => { + selectProviderAndDeleteWithOptionalFlashMessageCheck({ + createdProviderName, + assertDeleteFlashMessage: false, + }); + }); +} + +describe('Automate Cloud Provider form operations: Compute > Clouds > Providers > Configuration > Add a New Cloud Provider', () => { + beforeEach(() => { + cy.login(); + cy.menu( + COMPUTE_MENU_OPTION, + CLOUDS_AUTOMATION_MENU_OPTION, + PROVIDERS_MENU_OPTION + ); + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + }); + + describe('Validate cloud provider type: VMware vCloud', () => { + describe('Validate add form', () => { + it('Validate visibility of elements', () => { + validateVmwareVcloudFormFields(false); + }); + + it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { + fillVmwareVcloudForm({ + nameValue: `${VMWARE_VCLOUD_NAME_VALUE} - Verify add form validation error`, + hostValue: 'vmware-vcloud.verify-add-form-validation-error.com', + }); + validate({ + stubErrorResponse: true, + errorMessage: VMWARE_VCLOUD_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + add/refresh/delete operations', () => { + const nameFieldValue = `${VMWARE_VCLOUD_NAME_VALUE} - Verify validate/add/refresh/delete operations`; + fillVmwareVcloudForm({ + nameValue: nameFieldValue, + hostValue: + 'vmware-vcloud.verify-validate-add-refresh-delete-operations.com', + }); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + selectCreatedProvider(nameFieldValue); + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => + cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), + containsText: REFRESH_OPERATION_MESSAGE, + }); + cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); + + // FIXME: remove this block once bug is fixed + // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back + /* ==================================================================== */ + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + /* ==================================================================== */ + + selectProviderAndDeleteWithOptionalFlashMessageCheck({ + createdProviderName: nameFieldValue, + assertDeleteFlashMessage: true, + }); + }); + }); + + describe('Validate edit form', () => { + /** + * The provider name is set in this variable at the start of each test, + * allowing afterEach to identify it for deletion. + */ + let nameFieldValue; + + it('Validate visibility of elements', () => { + nameFieldValue = `${VMWARE_VCLOUD_NAME_VALUE} - Verify edit form elements`; + addVmwareVcloudProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'vmware-vcloud.verify-edit-form-elements.com', + }); + + validateVmwareVcloudFormFields(true); + }); + + it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { + nameFieldValue = `${VMWARE_VCLOUD_NAME_VALUE} - Verify edit form validation error`; + addVmwareVcloudProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'vmware-vcloud.verify-edit-form-validation-error.com', + }); + + cy.getFormSelectFieldById({ selectId: 'api_version' }).select( + API_VERSION_TYPE_V9 + ); + validate({ + stubErrorResponse: true, + errorMessage: VMWARE_VCLOUD_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.enabled') + .click(); + cy.getFormSelectFieldById({ selectId: 'api_version' }) + .find('option:selected') + .should('have.text', API_VERSION_TYPE_V5); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Cancel', + }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + edit operation', () => { + nameFieldValue = `${VMWARE_VCLOUD_NAME_VALUE} - Verify validate/edit operations`; + addVmwareVcloudProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'vmware-vcloud.verify-validate-edit-operations.com', + }); + + cy.getFormSelectFieldById({ selectId: 'api_version' }).select( + API_VERSION_TYPE_V9 + ); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Save', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + + describe('Provider name uniqueness validation', () => { + const nameFieldValue = `${VMWARE_VCLOUD_NAME_VALUE} - Verify duplicate restriction`; + + beforeEach(() => { + fillVmwareVcloudForm({ + nameValue: nameFieldValue, + hostValue: 'vmware-vcloud.verify-duplicate-restriction.com', + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + }); + + it('Should display error on duplicate name usage', () => { + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + fillVmwareVcloudForm({ + nameValue: nameFieldValue, + hostValue: 'vmware-vcloud.verify-duplicate-restriction.com', + }); + assertNameAlreadyExistsError(); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + }); + + describe('Validate cloud provider type: Oracle Cloud', () => { + describe('Validate add form', () => { + it('Validate visibility of elements', () => { + validateOracleCloudFormFields(false); + }); + + it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { + fillOracleCloudForm({ + nameValue: `${ORACLE_CLOUD_NAME_VALUE} - Verify add form validation error`, + }); + validate({ + stubErrorResponse: true, + errorMessage: ORACLE_CLOUD_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + add/refresh/delete operations', () => { + const nameValue = `${ORACLE_CLOUD_NAME_VALUE} - Verify validate/add/refresh/delete operations`; + fillOracleCloudForm({ + nameValue, + }); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + selectCreatedProvider(nameValue); + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => + cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), + containsText: REFRESH_OPERATION_MESSAGE, + }); + cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); + + // FIXME: remove this block once bug is fixed + // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back + /* ==================================================================== */ + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + /* ==================================================================== */ + + selectProviderAndDeleteWithOptionalFlashMessageCheck({ + createdProviderName: nameValue, + assertDeleteFlashMessage: true, + }); + }); + }); + + describe('Validate edit form', () => { + /** + * The provider name is set in this variable at the start of each test, + * allowing afterEach to identify it for deletion. + */ + let nameFieldValue; + + it('Validate visibility of elements', () => { + nameFieldValue = `${ORACLE_CLOUD_NAME_VALUE} - Verify edit form elements`; + addOracleCloudProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + validateOracleCloudFormFields(true); + }); + + it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { + nameFieldValue = `${ORACLE_CLOUD_NAME_VALUE} - Verify edit form validation error`; + addOracleCloudProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTION_MELBOURNE + ); + validate({ + stubErrorResponse: true, + errorMessage: ORACLE_CLOUD_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.enabled') + .click(); + cy.getFormSelectFieldById({ selectId: 'provider_region' }) + .find('option:selected') + .should('have.text', REGION_OPTION_HYDERABAD); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Cancel', + }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + edit operation', () => { + nameFieldValue = `${ORACLE_CLOUD_NAME_VALUE} - Verify validate/edit operations`; + addOracleCloudProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTION_MELBOURNE + ); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Save', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + + describe('Provider name uniqueness validation', () => { + const nameFieldValue = `${ORACLE_CLOUD_NAME_VALUE} - Verify duplicate restriction`; + + beforeEach(() => { + fillOracleCloudForm({ + nameValue: nameFieldValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + }); + + it('Should display error on duplicate name usage', () => { + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + fillOracleCloudForm({ + nameValue: nameFieldValue, + }); + assertNameAlreadyExistsError(); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + }); + + describe('Validate cloud provider type: IBM Cloud VPC', () => { + describe('Validate add form', () => { + it('Validate visibility of elements', () => { + validateIbmCloudVpcFormFields(false); + }); + + it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { + fillIbmCloudVpcForm({ + nameValue: `${IBM_CLOUD_VPC_NAME_VALUE} - Verify add form validation error`, + }); + validate({ + stubErrorResponse: true, + errorMessage: IBM_CLOUD_VPC_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + add/refresh/delete operations', () => { + const nameValue = `${IBM_CLOUD_VPC_NAME_VALUE} - Verify validate/add/refresh/delete operations`; + fillIbmCloudVpcForm({ + nameValue, + }); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + selectCreatedProvider(nameValue); + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => + cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), + containsText: REFRESH_OPERATION_MESSAGE, + }); + cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); + + // FIXME: remove this block once bug is fixed + // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back + /* ==================================================================== */ + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + /* ==================================================================== */ + + selectProviderAndDeleteWithOptionalFlashMessageCheck({ + createdProviderName: nameValue, + assertDeleteFlashMessage: true, + }); + }); + }); + + describe('Validate edit form', () => { + /** + * The provider name is set in this variable at the start of each test, + * allowing afterEach to identify it for deletion. + */ + let nameFieldValue; + + it('Validate visibility of elements', () => { + nameFieldValue = `${IBM_CLOUD_VPC_NAME_VALUE} - Verify edit form elements`; + addIbmCloudVpcProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + validateIbmCloudVpcFormFields(true); + }); + + it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { + nameFieldValue = `${IBM_CLOUD_VPC_NAME_VALUE} - Verify edit form validation error`; + addIbmCloudVpcProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTION_SPAIN + ); + validate({ + stubErrorResponse: true, + errorMessage: IBM_CLOUD_VPC_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.enabled') + .click(); + cy.getFormSelectFieldById({ selectId: 'provider_region' }) + .find('option:selected') + .should('have.text', REGION_OPTION_AUSTRALIA); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Cancel', + }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + edit operation', () => { + nameFieldValue = `${IBM_CLOUD_VPC_NAME_VALUE} - Verify validate/edit operations`; + addIbmCloudVpcProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTION_SPAIN + ); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Save', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + + describe('Provider name uniqueness validation', () => { + const nameFieldValue = `${IBM_CLOUD_VPC_NAME_VALUE} - Verify duplicate restriction`; + + beforeEach(() => { + fillIbmCloudVpcForm({ + nameValue: nameFieldValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + }); + + it('Should display error on duplicate name usage', () => { + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + fillIbmCloudVpcForm({ + nameValue: nameFieldValue, + }); + assertNameAlreadyExistsError(); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + }); + + describe('Validate cloud provider type: IBM Power Systems Virtual Servers', () => { + describe('Validate add form', () => { + it('Validate visibility of elements', () => { + validateIbmPowerSystemsVirtualServersFormFields(false); + }); + + it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { + fillIbmPowerSystemsVirtualServersForm({ + nameValue: `${IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_NAME_VALUE} - Verify add form validation error`, + }); + validate({ + stubErrorResponse: true, + errorMessage: IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + add/refresh/delete operations', () => { + const nameValue = `${IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_NAME_VALUE} - Verify validate/add/refresh/delete operations`; + fillIbmPowerSystemsVirtualServersForm({ + nameValue, + }); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + selectCreatedProvider(nameValue); + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => + cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), + containsText: REFRESH_OPERATION_MESSAGE, + }); + cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); + + // FIXME: remove this block once bug is fixed + // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back + /* ==================================================================== */ + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + /* ==================================================================== */ + + selectProviderAndDeleteWithOptionalFlashMessageCheck({ + createdProviderName: nameValue, + assertDeleteFlashMessage: true, + }); + }); + }); + + describe('Validate edit form', () => { + /** + * The provider name is set in this variable at the start of each test, + * allowing afterEach to identify it for deletion. + */ + let nameFieldValue; + + it('Validate visibility of elements', () => { + nameFieldValue = `${IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_NAME_VALUE} - Verify edit form elements`; + addIbmPowerSystemsVirtualServersProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + validateIbmPowerSystemsVirtualServersFormFields(true); + }); + + it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { + nameFieldValue = `${IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_NAME_VALUE} - Verify edit form validation error`; + addIbmPowerSystemsVirtualServersProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type('-xr4q'); + validate({ + stubErrorResponse: true, + errorMessage: IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.enabled') + .click(); + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).should( + 'have.value', + GUID_VALUE + ); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Cancel', + }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + edit operation', () => { + nameFieldValue = `${IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_NAME_VALUE} - Verify validate/edit operations`; + addIbmPowerSystemsVirtualServersProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type('-xr4q'); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Save', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ + createdProviderName: nameFieldValue, + }); + }); + }); + + describe('Provider name uniqueness validation', () => { + const nameFieldValue = `${IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_NAME_VALUE} - Verify duplicate restriction`; + + beforeEach(() => { + fillIbmPowerSystemsVirtualServersForm({ + nameValue: nameFieldValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + }); + + it('Should display error on duplicate name usage', () => { + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + fillIbmPowerSystemsVirtualServersForm({ + nameValue: nameFieldValue, + }); + assertNameAlreadyExistsError(); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ + createdProviderName: nameFieldValue, + }); + }); + }); + }); + + describe('Validate cloud provider type: Google Compute Engine', () => { + describe('Validate add form', () => { + it('Validate visibility of elements', () => { + validateGoogleComputeEngineFormFields(false); + }); + + it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { + fillGoogleComputeEngineForm({ + nameValue: `${GOOGLE_COMPUTE_ENGINE_NAME_VALUE} - Verify add form validation error`, + }); + validate({ + stubErrorResponse: true, + errorMessage: GOOGLE_COMPUTE_ENGINE_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + add/refresh/delete operations', () => { + const nameFieldValue = `${GOOGLE_COMPUTE_ENGINE_NAME_VALUE} - Verify validate/add/refresh/delete operations`; + fillGoogleComputeEngineForm({ + nameValue: nameFieldValue, + }); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + selectCreatedProvider(nameFieldValue); + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => + cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), + containsText: REFRESH_OPERATION_MESSAGE, + }); + cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); + + // FIXME: remove this block once bug is fixed + // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back + /* ==================================================================== */ + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + /* ==================================================================== */ + + selectProviderAndDeleteWithOptionalFlashMessageCheck({ + createdProviderName: nameFieldValue, + assertDeleteFlashMessage: true, + }); + }); + }); + + describe('Validate edit form', () => { + /** + * The provider name is set in this variable at the start of each test, + * allowing afterEach to identify it for deletion. + */ + let nameFieldValue; + + it('Validate visibility of elements', () => { + nameFieldValue = `${GOOGLE_COMPUTE_ENGINE_NAME_VALUE} - Verify edit form elements`; + addGoogleComputeEngineProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + validateGoogleComputeEngineFormFields(true); + }); + + it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { + nameFieldValue = `${GOOGLE_COMPUTE_ENGINE_NAME_VALUE} - Verify edit form validation error`; + addGoogleComputeEngineProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + cy.getFormInputFieldByIdAndType({ inputId: 'project' }).type('-76g1'); + validate({ + stubErrorResponse: true, + errorMessage: GOOGLE_COMPUTE_ENGINE_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.enabled') + .click(); + cy.getFormInputFieldByIdAndType({ inputId: 'project' }).should( + 'have.value', + PROJECT_ID_VALUE + ); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Cancel', + }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + edit operation', () => { + nameFieldValue = `${GOOGLE_COMPUTE_ENGINE_NAME_VALUE} - Verify validate/edit operations`; + addGoogleComputeEngineProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + cy.getFormInputFieldByIdAndType({ inputId: 'project' }).type('-76g1'); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Save', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + + describe('Provider name uniqueness validation', () => { + const nameFieldValue = `${GOOGLE_COMPUTE_ENGINE_NAME_VALUE} - Verify duplicate restriction`; + + beforeEach(() => { + fillGoogleComputeEngineForm({ + nameValue: nameFieldValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + }); + + it('Should display error on duplicate name usage', () => { + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + fillGoogleComputeEngineForm({ + nameValue: nameFieldValue, + }); + assertNameAlreadyExistsError(); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + }); + + describe('Validate cloud provider type: Azure Stack', () => { + describe('Validate add form', () => { + it('Validate visibility of elements', () => { + validateAzureStackFormFields(false); + }); + + it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { + fillAzureStackForm({ + nameValue: `${AZURE_STACK_NAME_VALUE} - Verify add form validation error`, + hostValue: 'azure-stack.verify-add-form-validation-error.com', + }); + validate({ + stubErrorResponse: true, + errorMessage: AZURE_STACK_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + add/refresh/delete operations', () => { + const nameFieldValue = `${AZURE_STACK_NAME_VALUE} - Verify validate/add/refresh/delete operations`; + fillAzureStackForm({ + nameValue: nameFieldValue, + hostValue: + 'azure-stack.verify-validate-add-refresh-delete-operations.com', + }); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.interceptApi({ + alias: 'addAzureStackProviderApi', + urlPattern: '/api/providers', + triggerFn: () => + cy + .getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .should('be.enabled') + .click(), + responseInterceptor: (req) => { + // Let the request go through to the server(so that the data is created) and then override + // the response statusCode to 200, server will return internal_server_error(500) since we are + // using mock values for fields like host, port, etc. + req.continue((res) => { + res.send(200); + }); + }, + }); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + selectCreatedProvider(nameFieldValue); + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => + cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), + containsText: REFRESH_OPERATION_MESSAGE, + }); + cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); + + // FIXME: Remove this block once bug is fixed + // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back + /* ==================================================================== */ + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + /* ==================================================================== */ + + selectProviderAndDeleteWithOptionalFlashMessageCheck({ + createdProviderName: nameFieldValue, + assertDeleteFlashMessage: true, + }); + }); + }); + + describe('Validate edit form', () => { + /** + * The provider name is set in this variable at the start of each test, + * allowing afterEach to identify it for deletion. + */ + let nameFieldValue; + + it('Validate visibility of elements', () => { + nameFieldValue = `${AZURE_STACK_NAME_VALUE} - Verify edit form elements`; + addAzureStackProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'azure-stack.verify-edit-form-elements.com', + }); + + validateAzureStackFormFields(true); + }); + + it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { + nameFieldValue = `${AZURE_STACK_NAME_VALUE} - Verify edit form validation error`; + addAzureStackProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'azure-stack.verify-edit-form-validation-error.com', + }); + + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }).select(SECURITY_PROTOCOL_NON_SSL); + validate({ + stubErrorResponse: true, + errorMessage: AZURE_STACK_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.enabled') + .click(); + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }) + .find('option:selected') + .should('have.text', SECURITY_PROTOCOL_SSL); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Cancel', + }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + edit operation', () => { + nameFieldValue = `${AZURE_STACK_NAME_VALUE} - Verify validate/edit operations`; + addAzureStackProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'azure-stack.verify-validate-edit-operations.com', + }); + + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }).select(SECURITY_PROTOCOL_NON_SSL); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.interceptApi({ + method: 'PATCH', + alias: 'editAzureStackProviderApi', + urlPattern: /\/api\/providers\/\d+/, + triggerFn: () => + cy + .getFormFooterButtonByTypeWithText({ + buttonText: 'Save', + buttonType: 'submit', + }) + .should('be.enabled') + .click(), + responseInterceptor: (req) => { + // Let the request go through to the server(so that the data is updated) and then override + // the response statusCode to 200, server will return internal_server_error(500) since we are + // using mock values for fields like host, port, etc. + req.continue((res) => { + res.send(200); + }); + }, + }); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + + describe('Provider name uniqueness validation', () => { + const nameFieldValue = `${AZURE_STACK_NAME_VALUE} - Verify duplicate restriction`; + + beforeEach(() => { + fillAzureStackForm({ + nameValue: nameFieldValue, + hostValue: 'azure-stack.verify-duplicate-restriction.com', + }); + validate({ + stubErrorResponse: false, + }); + cy.interceptApi({ + alias: 'addAzureStackProviderApi', + urlPattern: '/api/providers', + triggerFn: () => + cy + .getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .click(), + responseInterceptor: (req) => { + // Let the request go through to the server(so that the data is created) and then override + // the response statusCode to 200, server will return internal_server_error(500) since we are + // using mock values for fields like host, port, etc. + req.continue((res) => { + res.send(200); + }); + }, + }); + }); + + it('Should display error on duplicate name usage', () => { + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + fillAzureStackForm({ + nameValue: nameFieldValue, + hostValue: 'azure-stack.verify-duplicate-restriction.com', + }); + assertNameAlreadyExistsError(); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + }); + + describe('Validate cloud provider type: Azure', () => { + describe('Validate add form', () => { + it('Validate visibility of elements', () => { + validateAzureFormFields(false); + }); + + it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { + fillAzureForm({ + nameValue: `${AZURE_NAME_VALUE} - Verify add form validation error`, + }); + validate({ + stubErrorResponse: true, + errorMessage: AZURE_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + add/refresh/delete operations', () => { + const nameFieldValue = `${AZURE_NAME_VALUE} - Verify validate/add/refresh/delete operations`; + fillAzureForm({ + nameValue: nameFieldValue, + }); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + selectCreatedProvider(nameFieldValue); + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => + cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), + containsText: REFRESH_OPERATION_MESSAGE, + }); + cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); + + // TODO: remove this block once bug is fixed + // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back + /* ==================================================================== */ + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + /* ==================================================================== */ + + selectProviderAndDeleteWithOptionalFlashMessageCheck({ + createdProviderName: nameFieldValue, + assertDeleteFlashMessage: true, + }); + }); + }); + + describe('Validate edit form', () => { + /** + * The provider name is set in this variable at the start of each test, + * allowing afterEach to identify it for deletion. + */ + let nameFieldValue; + + it('Validate visibility of elements', () => { + nameFieldValue = `${AZURE_NAME_VALUE} - Verify edit form elements`; + addAzureProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + validateAzureFormFields(true); + }); + + it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { + nameFieldValue = `${AZURE_NAME_VALUE} - Verify edit form validation error`; + addAzureProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTION_CENTRAL_US + ); + validate({ + stubErrorResponse: true, + errorMessage: AZURE_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.enabled') + .click(); + cy.getFormSelectFieldById({ selectId: 'provider_region' }) + .find('option:selected') + .should('have.text', REGION_OPTION_CENTRAL_INDIA); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + edit operation', () => { + nameFieldValue = `${AZURE_NAME_VALUE} - Verify validate/edit operations`; + addAzureProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTION_CENTRAL_US + ); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Save', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + + describe('Provider name uniqueness validation', () => { + const nameFieldValue = `${AZURE_NAME_VALUE} - Verify duplicate restriction`; + + beforeEach(() => { + fillAzureForm({ + nameValue: nameFieldValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + }); + + it('Should display error on duplicate name usage', () => { + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + fillAzureForm({ + nameValue: nameFieldValue, + }); + assertNameAlreadyExistsError(); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + }); + + describe('Validate cloud provider type: Amazon EC2', () => { + describe('Validate add form', () => { + it('Validate visibility of elements', () => { + validateAmazonEC2FormFields(false); + }); + + it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { + fillAmazonEC2Form({ + nameValue: `${AMAZON_EC2_NAME_VALUE} - Verify add form validation error`, + }); + validate({ + stubErrorResponse: true, + errorMessage: AMAZON_EC2_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + add/refresh/delete operations', () => { + const nameFieldValue = `${AMAZON_EC2_NAME_VALUE} - Verify validate/add/refresh/delete operations`; + fillAmazonEC2Form({ + nameValue: nameFieldValue, + }); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + selectCreatedProvider(nameFieldValue); + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => + cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), + containsText: REFRESH_OPERATION_MESSAGE, + }); + cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); + + // TODO: remove this block once bug is fixed + // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back + /* ==================================================================== */ + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + /* ==================================================================== */ + + selectProviderAndDeleteWithOptionalFlashMessageCheck({ + createdProviderName: nameFieldValue, + assertDeleteFlashMessage: true, + }); + }); + }); + + describe('Validate edit form', () => { + /** + * The provider name is set in this variable at the start of each test, + * allowing afterEach to identify it for deletion. + */ + let nameFieldValue; + + it('Validate visibility of elements', () => { + nameFieldValue = `${AMAZON_EC2_NAME_VALUE} - Verify edit form elements`; + addAmazonEC2ProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + validateAmazonEC2FormFields(true); + }); + + it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { + nameFieldValue = `${AMAZON_EC2_NAME_VALUE} - Verify edit form validation error`; + addAmazonEC2ProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTION_ASIA_PACIFIC + ); + validate({ + stubErrorResponse: true, + errorMessage: AMAZON_EC2_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.enabled') + .click(); + cy.getFormSelectFieldById({ selectId: 'provider_region' }) + .find('option:selected') + .should('have.text', REGION_OPTION_CANADA); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + edit operation', () => { + nameFieldValue = `${AMAZON_EC2_NAME_VALUE} - Verify validate/edit operations`; + addAmazonEC2ProviderAndOpenEditForm({ + nameValue: nameFieldValue, + }); + + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTION_ASIA_PACIFIC + ); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Save', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + + describe('Provider name uniqueness validation', () => { + const nameFieldValue = `${AMAZON_EC2_NAME_VALUE} - Verify duplicate restriction`; + + beforeEach(() => { + fillAmazonEC2Form({ + nameValue: nameFieldValue, + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + }); + + it('Should display error on duplicate name usage', () => { + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + fillAmazonEC2Form({ + nameValue: nameFieldValue, + }); + assertNameAlreadyExistsError(); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + }); + + describe('Validate cloud provider type: IBM PowerVC', () => { + describe('Validate add form', () => { + it('Validate visibility of elements', () => { + validateIbmPowerVcFormFields(false); + }); + + it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { + fillIbmPowerVcForm({ + nameValue: `${IBM_POWERVC_NAME_VALUE} - Verify add form validation error`, + hostValue: 'ibm-powervc.verify-add-form-validation-error.com', + }); + validate({ + stubErrorResponse: true, + errorMessage: IBM_POWERVC_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + add/refresh/delete operations', () => { + const nameFieldValue = `${IBM_POWERVC_NAME_VALUE} - Verify validate/add/refresh/delete operations`; + fillIbmPowerVcForm({ + nameValue: nameFieldValue, + hostValue: + 'ibm-powervc.verify-validate-add-refresh-delete-operations.com', + }); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + selectCreatedProvider(nameFieldValue); + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => + cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), + containsText: REFRESH_OPERATION_MESSAGE, + }); + cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); + + // TODO: remove this block once bug is fixed + // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back + /* ==================================================================== */ + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + /* ==================================================================== */ + + selectProviderAndDeleteWithOptionalFlashMessageCheck({ + createdProviderName: nameFieldValue, + assertDeleteFlashMessage: true, + }); + }); + }); + + describe('Validate edit form', () => { + /** + * The provider name is set in this variable at the start of each test, + * allowing afterEach to identify it for deletion. + */ + let nameFieldValue; + + it('Validate visibility of elements', () => { + nameFieldValue = `${IBM_POWERVC_NAME_VALUE} - Verify edit form elements`; + addIbmPowerVcProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'ibm-powervc.verify-edit-form-elements.com', + }); + + validateIbmPowerVcFormFields(true); + }); + + it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { + nameFieldValue = `${IBM_POWERVC_NAME_VALUE} - Verify edit form validation error`; + addIbmPowerVcProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'ibm-powervc.verify-edit-form-validation-error.com', + }); + + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }).select(SECURITY_PROTOCOL_NON_SSL); + validate({ + stubErrorResponse: true, + errorMessage: IBM_POWERVC_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.enabled') + .click(); + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }) + .find('option:selected') + .should('have.text', SECURITY_PROTOCOL_SSL); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + edit operation', () => { + nameFieldValue = `${IBM_POWERVC_NAME_VALUE} - Verify validate/edit operations`; + addIbmPowerVcProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'ibm-powervc.verify-validate-edit-operations.com', + }); + + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }).select(SECURITY_PROTOCOL_NON_SSL); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Save', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + + describe('Provider name uniqueness validation', () => { + const nameFieldValue = `${IBM_POWERVC_NAME_VALUE} - Verify duplicate restriction`; + + beforeEach(() => { + fillIbmPowerVcForm({ + nameValue: nameFieldValue, + hostValue: 'ibm-powervc.verify-duplicate-restriction.com', + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + }); + + it('Should display error on duplicate name usage', () => { + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + fillIbmPowerVcForm({ + nameValue: nameFieldValue, + hostValue: 'ibm-powervc.verify-duplicate-restriction.com', + }); + assertNameAlreadyExistsError(); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + }); + + describe('Validate cloud provider type: IBM Cloud Infrastructure Center', () => { + describe('Validate add form', () => { + it('Validate visibility of elements', () => { + validateIbmCloudInfrastructureCenterFormFields(false); + }); + + it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { + fillIbmCloudInfrastructureCenterForm({ + nameValue: `${IBM_CIC_NAME_VALUE} - Verify add form validation error`, + hostValue: 'ibm-cic.verify-add-form-validation-error.com', + }); + validate({ + stubErrorResponse: true, + errorMessage: IBM_CIC_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + add/refresh/delete operations', () => { + const nameFieldValue = `${IBM_CIC_NAME_VALUE} - Verify validate/add/refresh/delete operations`; + fillIbmCloudInfrastructureCenterForm({ + nameValue: nameFieldValue, + hostValue: + 'ibm-cic.verify-validate-add-refresh-delete-operations.com', + }); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + selectCreatedProvider(nameFieldValue); + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => + cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), + containsText: REFRESH_OPERATION_MESSAGE, + }); + cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); + + // TODO: remove this block once bug is fixed + // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back + /* ==================================================================== */ + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + /* ==================================================================== */ + + selectProviderAndDeleteWithOptionalFlashMessageCheck({ + createdProviderName: nameFieldValue, + assertDeleteFlashMessage: true, + }); + }); + }); + + describe('Validate edit form', () => { + /** + * The provider name is set in this variable at the start of each test, + * allowing afterEach to identify it for deletion. + */ + let nameFieldValue; + + it('Validate visibility of elements', () => { + nameFieldValue = `${IBM_CIC_NAME_VALUE} - Verify edit form elements`; + addIbmCloudInfrastructureCenterProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'ibm-cic.verify-edit-form-elements.com', + }); + + validateIbmCloudInfrastructureCenterFormFields(true); + }); + + it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { + nameFieldValue = `${IBM_CIC_NAME_VALUE} - Verify edit form validation error`; + addIbmCloudInfrastructureCenterProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'ibm-cic.verify-edit-form-validation-error.com', + }); + + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }).select(SECURITY_PROTOCOL_NON_SSL); + validate({ + stubErrorResponse: true, + errorMessage: IBM_CIC_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.enabled') + .click(); + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }) + .find('option:selected') + .should('have.text', SECURITY_PROTOCOL_SSL); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + edit operation', () => { + nameFieldValue = `${IBM_CIC_NAME_VALUE} - Verify validate/edit operations`; + addIbmCloudInfrastructureCenterProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'ibm-cic.verify-validate-edit-operations.com', + }); + + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }).select(SECURITY_PROTOCOL_NON_SSL); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Save', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + + describe('Provider name uniqueness validation', () => { + const nameFieldValue = `${IBM_CIC_NAME_VALUE} - Verify duplicate restriction`; + + beforeEach(() => { + fillIbmCloudInfrastructureCenterForm({ + nameValue: nameFieldValue, + hostValue: 'ibm-cic.verify-duplicate-restriction.com', + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + }); + + it('Should display error on duplicate name usage', () => { + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + fillIbmCloudInfrastructureCenterForm({ + nameValue: nameFieldValue, + hostValue: 'ibm-cic.verify-duplicate-restriction.com', + }); + assertNameAlreadyExistsError(); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + }); + + describe('Validate cloud provider type: Openstack', () => { + describe('Validate add form', () => { + it('Validate visibility of elements', () => { + validateOpenstackFormFields(false); + }); + + it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { + fillOpenstackForm({ + nameValue: `${OPENSTACK_NAME_VALUE} - Verify add form validation error`, + hostValue: 'openstack.verify-add-form-validation-error.com', + }); + validate({ + stubErrorResponse: true, + errorMessage: OPENSTACK_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + add/refresh/delete operations', () => { + const nameFieldValue = `${OPENSTACK_NAME_VALUE} - Verify validate/add/refresh/delete operations`; + fillOpenstackForm({ + nameValue: nameFieldValue, + hostValue: + 'openstack.verify-validate-add-refresh-delete-operations.com', + }); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + selectCreatedProvider(nameFieldValue); + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => + cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), + containsText: REFRESH_OPERATION_MESSAGE, + }); + cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); + + // TODO: remove this block once bug is fixed + // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back + /* ==================================================================== */ + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + /* ==================================================================== */ + + selectProviderAndDeleteWithOptionalFlashMessageCheck({ + createdProviderName: nameFieldValue, + assertDeleteFlashMessage: true, + }); + }); + }); + + describe('Validate edit form', () => { + /** + * The provider name is set in this variable at the start of each test, + * allowing afterEach to identify it for deletion. + */ + let nameFieldValue; + + it('Validate visibility of elements', () => { + nameFieldValue = `${OPENSTACK_NAME_VALUE} - Verify edit form elements`; + addOpenstackProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'openstack.verify-edit-form-elements.com', + }); + + validateOpenstackFormFields(true); + }); + + it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { + nameFieldValue = `${OPENSTACK_NAME_VALUE} - Verify edit form validation error`; + addOpenstackProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'openstack.verify-edit-form-validation-error.com', + }); + + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }).select(SECURITY_PROTOCOL_NON_SSL); + validate({ + stubErrorResponse: true, + errorMessage: OPENSTACK_VALIDATION_ERROR, + }); + assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.enabled') + .click(); + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }) + .find('option:selected') + .should('have.text', SECURITY_PROTOCOL_SSL); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGE_OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + edit operation', () => { + nameFieldValue = `${OPENSTACK_NAME_VALUE} - Verify validate/edit operations`; + addOpenstackProviderAndOpenEditForm({ + nameValue: nameFieldValue, + hostValue: 'openstack.verify-validate-edit-operations.com', + }); + + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }).select(SECURITY_PROTOCOL_NON_SSL); + validate({ + stubErrorResponse: false, + }); + assertValidationSuccessMessage(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Save', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + + describe('Provider name uniqueness validation', () => { + const nameFieldValue = `${OPENSTACK_NAME_VALUE} - Verify duplicate restriction`; + + beforeEach(() => { + fillOpenstackForm({ + nameValue: nameFieldValue, + hostValue: 'openstack.verify-duplicate-restriction.com', + }); + validate({ + stubErrorResponse: false, + }); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); + }); + + it('Should display error on duplicate name usage', () => { + cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); + fillOpenstackForm({ + nameValue: nameFieldValue, + hostValue: 'openstack.verify-duplicate-restriction.com', + }); + assertNameAlreadyExistsError(); + }); + + afterEach(() => { + // TODO: add better clean up approach + cleanUp({ createdProviderName: nameFieldValue }); + }); + }); + }); +}); From 0cfc104cdc4cb79ce635d3657c436a504352c1e4 Mon Sep 17 00:00:00 2001 From: asirvadAbrahamVarghese Date: Tue, 7 Oct 2025 11:14:45 +0530 Subject: [PATCH 2/4] Adding helpers for pluggable approach --- .../Clouds/Providers/provider-factory.js | 1108 +++++++++++++++++ .../commands/provider_helper_commands.js | 890 +++++++++++++ cypress/support/e2e.js | 1 + 3 files changed, 1999 insertions(+) create mode 100644 cypress/e2e/ui/Compute/Clouds/Providers/provider-factory.js create mode 100644 cypress/support/commands/provider_helper_commands.js diff --git a/cypress/e2e/ui/Compute/Clouds/Providers/provider-factory.js b/cypress/e2e/ui/Compute/Clouds/Providers/provider-factory.js new file mode 100644 index 00000000000..550c6c770e1 --- /dev/null +++ b/cypress/e2e/ui/Compute/Clouds/Providers/provider-factory.js @@ -0,0 +1,1108 @@ +/** + * Provider Factory - Creates configuration objects for different cloud provider types + * This factory makes it easy to add new provider types with minimal code changes + */ + +// Common field labels +export const FIELD_LABELS = { + TYPE: 'Type', + NAME: 'Name', + ZONE: 'Zone', + API_VERSION: 'API Version', + HOSTNAME: 'Hostname (or IPv4 or IPv6 address)', + API_PORT: 'API Port', + USERNAME: 'Username', + PASSWORD: 'Password', + SECURITY_PROTOCOL: 'Security Protocol', + REGION: 'Region', + TENANT_ID: 'Tenant ID', + DOMAIN_ID: 'Domain ID', + USER_ID: 'User ID', + PUBLIC_KEY: 'Public Key', + PRIVATE_KEY: 'Private Key', + IBM_CLOUD: 'IBM Cloud', + SERVICE: 'Service', + PROJECT_ID: 'Project ID', + SUBSCRIPTION_ID: 'Subscription ID', + ENDPOINT_URL: 'Endpoint URL', + CLIENT_ID: 'Client ID', + CLIENT_KEY: 'Client Key', + ASSUME_ROLE_ARN: 'Assume role ARN', + ACCESS_KEY_ID: 'Access Key ID', + SECRET_ACCESS_KEY: 'Secret Access Key', + PROVIDER_REGION: 'Provider Region', + OPENSTACK_INFRA_PROVIDER: 'Openstack Infra Provider', + POWERVC_API_ENDPOINT: 'PowerVC API Endpoint (Hostname or IPv4/IPv6 address)', + ANSIBLE_ACCESS_METHOD: 'Ansible Access Method', + TENANT_MAPPING_ENABLED: 'Tenant Mapping Enabled', + API_USERNAME: 'API Username', + API_PASSWORD: 'API Password', + POWERVC: 'PowerVC', +}; + +// Common tab labels +export const TAB_LABELS = { + DEFAULT: 'Default', + EVENTS: 'Events', + METRICS: 'Metrics', + RSA_KEY_PAIR: 'RSA key pair', + IMAGE_EXPORT: 'Image Export', + SMARTSTATE_DOCKER: 'SmartState Docker', +}; + +// Common select options +export const SELECT_OPTIONS = { + EVENT_STREAM_TYPE_AMQP: 'AMQP', + EVENT_STREAM_TYPE_STF: 'STF', + ENABLED: 'Enabled', + API_VERSION_V3: 'Keystone V3', + API_VERSION_V5: 'vCloud API 5.5', + API_VERSION_V9: 'vCloud API 9.0', + API_VERSION_2017: 'V2017_03_09', + ZONE_DEFAULT: 'default', + SECURITY_PROTOCOL_SSL: 'SSL', + SECURITY_PROTOCOL_NON_SSL: 'Non-SSL', +}; + +// Common region options +export const REGION_OPTIONS = { + CENTRAL_INDIA: 'Central India', + CENTRAL_US: 'Central US', + HYDERABAD: 'ap-hyderabad-1', + MELBOURNE: 'ap-melbourne-1', + AUSTRALIA: 'Australia (Sydney)', + SPAIN: 'EU Spain (Madrid)', + CANADA: 'Canada (Central)', + ASIA_PACIFIC: 'Asia Pacific (Malaysia)', +}; + +// Common field values +export const FIELD_VALUES = { + TEST_NAME: 'Test Name:', + TENANT_ID: '101', + SUBSCRIPTION_ID: 'z565815f-05b6-402f-1999-045155da7dq4', + ENDPOINT_URL: '/api', + CLIENT_ID: 'manageiq.example.com', + CLIENT_KEY: 'test_client_key', + PORT: '3000', + USERNAME: 'admin@example.com', + PASSWORD: 'password123', + PRIVATE_KEY: + '-----BEGIN PRIVATE KEY-----\nMIIEvQIBAzApPugkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC\n-----END PRIVATE KEY-----', + PUBLIC_KEY: + '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAz14iAAOCAQ8AMIIBCgKCAQEA\n-----END PUBLIC KEY-----', + CLOUD_API_KEY: 'ibm_cloud_api_key_k#157', + GUID: '723e4a67-e89b-1qd3-z486-920614074000', + PROJECT_ID: 'gcp-project-123456', + ASSUME_ROLE: 'arn:aws:iam::123456789012:role/ManageIQRole', + ACCESS_KEY_ID: 'AKIAIOSFODNN7EXAMPLE', + SECRET_ACCESS_KEY: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY', + DOMAIN_ID_DEFAULT: 'default', + PROVIDER_REGION: 'RegionOne', +}; + +// Common flash message text snippets +export const FLASH_MESSAGES = { + OPERATION_CANCELLED: 'cancelled', + OPERATION_SAVED: 'saved', + DELETE_OPERATION: 'delete', + REFRESH_OPERATION: 'Refresh', + REMOVE_PROVIDER_BROWSER_ALERT: 'removed', +}; + +// Common validation messages +export const VALIDATION_MESSAGES = { + FAILED: 'Validation failed', + SUCCESSFUL: 'Validation successful', + NAME_ALREADY_EXISTS: 'already exists', +}; + +// Provider-specific validation error messages +export const VALIDATION_ERRORS = { + VMWARE_VCLOUD: 'Socket error: no address for example.manageiq.com', + ORACLE_CLOUD: 'The format of tenancy is invalid.', + IBM_CLOUD_VPC: 'Provided API key could not be found.', + IBM_POWER_SYSTEMS_VIRTUAL_SERVERS: 'IAM authentication failed', + GOOGLE_COMPUTE_ENGINE: 'Invalid Google JSON key', + AZURE_STACK: 'Failed to open TCP connection to example.manageiq.com:3000', + AZURE: 'Incorrect credentials - no host component for URI', + AMAZON_EC2: 'The security token included in the request is invalid.', + IBM_POWERVC: 'unable to retrieve IBM PowerVC release version number', + IBM_CIC: 'Login attempt timed out', + OPENSTACK: 'Socket error: no address for example.manageiq.com', +}; + +// Provider types +export const PROVIDER_TYPES = { + VMWARE_VCLOUD: 'VMware vCloud', + AZURE_STACK: 'Azure Stack', + IBM_CLOUD_VPC: 'IBM Cloud VPC', + IBM_POWER_SYSTEMS: 'IBM Power Systems Virtual Servers', + GOOGLE_COMPUTE: 'Google Compute Engine', + ORACLE_CLOUD: 'Oracle Cloud', + AZURE: 'Azure', + AMAZON_EC2: 'Amazon EC2', + IBM_POWERVC: 'IBM PowerVC', + IBM_CIC: 'IBM Cloud Infrastructure Center', + OPENSTACK: 'OpenStack', +}; + +/** + * Creates a provider configuration object with all necessary properties + * @param {string} type - The provider type + * @param {Object} config - Additional configuration options + * @returns {Object} - The provider configuration object + */ +function createProviderConfig(type, config = {}) { + const baseConfig = { + type, + nameValue: `${FIELD_VALUES.TEST_NAME} ${type}`, + validationError: VALIDATION_ERRORS[type.replace(/\s+/g, '_').toUpperCase()], + formFields: { + common: [ + { + label: FIELD_LABELS.TYPE, + id: 'type', + type: 'select', + required: true, + }, + { label: FIELD_LABELS.NAME, id: 'name', type: 'text', required: true }, + { + label: FIELD_LABELS.ZONE, + id: 'zone_id', + type: 'select', + required: true, + }, + ], + }, + formValues: { + common: { + type, + name: `${FIELD_VALUES.TEST_NAME} ${type}`, + zone_id: SELECT_OPTIONS.ZONE_DEFAULT, + }, + }, + fieldSelectionValues: {}, + }; + + // Merge with provided config + return { ...baseConfig, ...config }; +} + +/** + * Creates a VMware vCloud provider configuration + * @returns {Object} - The provider configuration + */ +function getVMwareVcloudProviderConfig() { + return createProviderConfig(PROVIDER_TYPES.VMWARE_VCLOUD, { + formFields: { + default: [ + { + label: FIELD_LABELS.API_VERSION, + id: 'api_version', + type: 'select', + required: true, + }, + { + label: FIELD_LABELS.HOSTNAME, + id: 'endpoints.default.hostname', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.API_PORT, + id: 'endpoints.default.port', + type: 'number', + required: true, + }, + { + label: FIELD_LABELS.USERNAME, + id: 'authentications.default.userid', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.PASSWORD, + id: 'authentications.default.password', + type: 'password', + required: true, + isPlaceholderInEditMode: true, + }, + ], + events: [ + { + label: FIELD_LABELS.TYPE, + id: 'event_stream_selection', + type: 'select', + required: false, + }, + { + label: FIELD_LABELS.SECURITY_PROTOCOL, + id: 'endpoints.amqp.security_protocol', + type: 'select', + required: false, + }, + { + label: FIELD_LABELS.HOSTNAME, + id: 'endpoints.amqp.hostname', + type: 'text', + required: false, + }, + { + label: FIELD_LABELS.API_PORT, + id: 'endpoints.amqp.port', + type: 'number', + required: false, + }, + { + label: FIELD_LABELS.USERNAME, + id: 'authentications.amqp.userid', + type: 'text', + required: false, + }, + { + label: FIELD_LABELS.PASSWORD, + id: 'authentications.amqp.password', + type: 'password', + required: false, + isPlaceholderInEditMode: true, + }, + ], + }, + formValues: { + default: { + api_version: SELECT_OPTIONS.API_VERSION_V5, + 'endpoints.default.port': FIELD_VALUES.PORT, + 'authentications.default.userid': FIELD_VALUES.USERNAME, + 'authentications.default.password': FIELD_VALUES.PASSWORD, + }, + }, + fieldSelectionValues: { + events: { + event_stream_selection: [SELECT_OPTIONS.EVENT_STREAM_TYPE_AMQP], + }, + }, + tabs: [TAB_LABELS.DEFAULT, TAB_LABELS.EVENTS], + }); +} + +/** + * Creates an Oracle Cloud provider configuration + * @returns {Object} - The provider configuration + */ +function getOracleCloudProviderConfig() { + return createProviderConfig(PROVIDER_TYPES.ORACLE_CLOUD, { + formFields: { + default: [ + { + label: FIELD_LABELS.REGION, + id: 'provider_region', + type: 'select', + required: true, + }, + { + label: FIELD_LABELS.TENANT_ID, + id: 'uid_ems', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.USER_ID, + id: 'authentications.default.userid', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.PRIVATE_KEY, + id: 'authentications.default.auth_key', + type: 'textarea', + required: true, + isPlaceholderInEditMode: true, + }, + { + label: FIELD_LABELS.PUBLIC_KEY, + id: 'authentications.default.public_key', + type: 'textarea', + required: true, + }, + ], + }, + formValues: { + default: { + provider_region: REGION_OPTIONS.HYDERABAD, + uid_ems: FIELD_VALUES.TENANT_ID, + 'authentications.default.userid': FIELD_VALUES.USERNAME, + 'authentications.default.auth_key': FIELD_VALUES.PRIVATE_KEY, + 'authentications.default.public_key': FIELD_VALUES.PUBLIC_KEY, + }, + }, + tabs: [TAB_LABELS.DEFAULT], + }); +} + +/** + * Creates an IBM Cloud VPC provider configuration + * @returns {Object} - The provider configuration + */ +function getIBMCloudVPCProviderConfig() { + return createProviderConfig(PROVIDER_TYPES.IBM_CLOUD_VPC, { + formFields: { + default: [ + { + label: FIELD_LABELS.REGION, + id: 'provider_region', + type: 'select', + required: true, + }, + { + label: FIELD_LABELS.IBM_CLOUD, + id: 'authentications.default.auth_key', + type: 'password', + required: true, + isPlaceholderInEditMode: true, + }, + ], + metrics: [ + { + label: FIELD_LABELS.TYPE, + id: 'metrics_selection', + type: 'select', + required: false, + }, + { + label: FIELD_LABELS.IBM_CLOUD, + id: 'endpoints.metrics.options.monitoring_instance_id', + type: 'password', + required: false, + }, + ], + events: [ + { + label: FIELD_LABELS.TYPE, + id: 'events_selection', + type: 'select', + required: false, + }, + { + label: FIELD_LABELS.IBM_CLOUD, + id: 'authentications.events.auth_key', + type: 'password', + required: false, + }, + ], + }, + formValues: { + default: { + provider_region: REGION_OPTIONS.AUSTRALIA, + 'authentications.default.auth_key': FIELD_VALUES.CLOUD_API_KEY, + }, + }, + fieldSelectionValues: { + metrics: { + metrics_selection: SELECT_OPTIONS.ENABLED, + }, + events: { + events_selection: SELECT_OPTIONS.ENABLED, + }, + }, + tabs: [TAB_LABELS.DEFAULT, TAB_LABELS.METRICS, TAB_LABELS.EVENTS], + }); +} + +/** + * Creates an IBM Power Systems Virtual Servers provider configuration + * @returns {Object} - The provider configuration + */ +function getIBMPowerSystemsProviderConfig() { + return createProviderConfig(PROVIDER_TYPES.IBM_POWER_SYSTEMS, { + formFields: { + default: [ + { + label: FIELD_LABELS.IBM_CLOUD, + id: 'authentications.default.auth_key', + type: 'password', + required: true, + isPlaceholderInEditMode: true, + }, + { + label: FIELD_LABELS.SERVICE, + id: 'uid_ems', + type: 'text', + required: true, + }, + ], + }, + formValues: { + default: { + 'authentications.default.auth_key': FIELD_VALUES.CLOUD_API_KEY, + uid_ems: FIELD_VALUES.GUID, + }, + }, + tabs: [TAB_LABELS.DEFAULT], + }); +} + +/** + * Creates a Google Compute Engine provider configuration + * @returns {Object} - The provider configuration + */ +function getGoogleComputeEngineProviderConfig() { + return createProviderConfig(PROVIDER_TYPES.GOOGLE_COMPUTE, { + formFields: { + default: [ + { + label: FIELD_LABELS.PROJECT_ID, + id: 'project', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.SERVICE, + id: 'authentications.default.auth_key', + type: 'textarea', + required: true, + isPlaceholderInEditMode: true, + }, + ], + }, + formValues: { + default: { + project: FIELD_VALUES.PROJECT_ID, + 'authentications.default.auth_key': `{"type":"service_account","project_id":"${FIELD_VALUES.PROJECT_ID}","private_key":"${FIELD_VALUES.PRIVATE_KEY}"}`, + }, + }, + tabs: [TAB_LABELS.DEFAULT], + }); +} + +/** + * Creates an Azure Stack provider configuration + * @returns {Object} - The provider configuration + */ +function getAzureStackProviderConfig() { + return createProviderConfig(PROVIDER_TYPES.AZURE_STACK, { + formFields: { + default: [ + { + label: FIELD_LABELS.TENANT_ID, + id: 'uid_ems', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.SUBSCRIPTION_ID, + id: 'subscription', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.API_VERSION, + id: 'api_version', + type: 'select', + required: true, + }, + { + label: FIELD_LABELS.SECURITY_PROTOCOL, + id: 'endpoints.default.security_protocol', + type: 'select', + required: true, + }, + { + label: FIELD_LABELS.HOSTNAME, + id: 'endpoints.default.hostname', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.API_PORT, + id: 'endpoints.default.port', + type: 'number', + required: true, + }, + { + label: FIELD_LABELS.USERNAME, + id: 'authentications.default.userid', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.PASSWORD, + id: 'authentications.default.password', + type: 'password', + required: true, + isPlaceholderInEditMode: true, + }, + ], + }, + formValues: { + default: { + uid_ems: FIELD_VALUES.TENANT_ID, + subscription: FIELD_VALUES.SUBSCRIPTION_ID, + api_version: SELECT_OPTIONS.API_VERSION_2017, + 'endpoints.default.security_protocol': + SELECT_OPTIONS.SECURITY_PROTOCOL_SSL, + 'endpoints.default.port': FIELD_VALUES.PORT, + 'authentications.default.userid': FIELD_VALUES.USERNAME, + 'authentications.default.password': FIELD_VALUES.PASSWORD, + }, + }, + tabs: [TAB_LABELS.DEFAULT], + }); +} + +/** + * Creates an Azure provider configuration + * @returns {Object} - The provider configuration + */ +function getAzureProviderConfig() { + return createProviderConfig(PROVIDER_TYPES.AZURE, { + formFields: { + default: [ + { + label: FIELD_LABELS.REGION, + id: 'provider_region', + type: 'select', + required: true, + }, + { + label: FIELD_LABELS.TENANT_ID, + id: 'uid_ems', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.SUBSCRIPTION_ID, + id: 'subscription', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.ENDPOINT_URL, + id: 'endpoints.default.url', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.CLIENT_ID, + id: 'authentications.default.userid', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.CLIENT_KEY, + id: 'authentications.default.password', + type: 'password', + required: true, + isPlaceholderInEditMode: true, + }, + ], + }, + formValues: { + default: { + provider_region: REGION_OPTIONS.CENTRAL_INDIA, + uid_ems: FIELD_VALUES.TENANT_ID, + subscription: FIELD_VALUES.SUBSCRIPTION_ID, + 'endpoints.default.url': FIELD_VALUES.ENDPOINT_URL, + 'authentications.default.userid': FIELD_VALUES.CLIENT_ID, + 'authentications.default.password': FIELD_VALUES.CLIENT_KEY, + }, + }, + tabs: [TAB_LABELS.DEFAULT], + }); +} + +/** + * Creates an Amazon EC2 provider configuration + * @returns {Object} - The provider configuration + */ +function getAmazonEC2ProviderConfig() { + return createProviderConfig(PROVIDER_TYPES.AMAZON_EC2, { + formFields: { + default: [ + { + label: FIELD_LABELS.REGION, + id: 'provider_region', + type: 'select', + required: true, + }, + { + label: FIELD_LABELS.ENDPOINT_URL, + id: 'endpoints.default.url', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.ASSUME_ROLE_ARN, + id: 'authentications.default.service_account', + type: 'text', + required: false, + }, + { + label: FIELD_LABELS.ACCESS_KEY_ID, + id: 'authentications.default.userid', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.SECRET_ACCESS_KEY, + id: 'authentications.default.password', + type: 'password', + required: true, + isPlaceholderInEditMode: true, + }, + ], + smartstate_docker: [ + { + label: FIELD_LABELS.USERNAME, + id: 'authentications.smartstate_docker.userid', + type: 'text', + required: false, + }, + { + label: FIELD_LABELS.PASSWORD, + id: 'authentications.smartstate_docker.password', + type: 'password', + required: false, + isPlaceholderInEditMode: true, + }, + ], + }, + formValues: { + default: { + provider_region: REGION_OPTIONS.CANADA, + 'endpoints.default.url': FIELD_VALUES.ENDPOINT_URL, + 'authentications.default.service_account': FIELD_VALUES.ASSUME_ROLE, + 'authentications.default.userid': FIELD_VALUES.ACCESS_KEY_ID, + 'authentications.default.password': FIELD_VALUES.SECRET_ACCESS_KEY, + }, + }, + tabs: [TAB_LABELS.DEFAULT, TAB_LABELS.SMARTSTATE_DOCKER], + }); +} + +/** + * Creates an IBM PowerVC provider configuration + * @returns {Object} - The provider configuration + */ +function getIBMPowerVCProviderConfig() { + return createProviderConfig(PROVIDER_TYPES.IBM_POWERVC, { + formFields: { + default: [ + { + label: FIELD_LABELS.PROVIDER_REGION, + id: 'provider_region', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.TENANT_MAPPING_ENABLED, + id: 'tenant_mapping_enabled', + type: 'checkbox', + required: false, + }, + { + label: FIELD_LABELS.SECURITY_PROTOCOL, + id: 'endpoints.default.security_protocol', + type: 'select', + required: true, + }, + { + label: FIELD_LABELS.POWERVC_API_ENDPOINT, + id: 'endpoints.default.hostname', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.API_PORT, + id: 'endpoints.default.port', + type: 'number', + required: true, + }, + { + label: FIELD_LABELS.API_USERNAME, + id: 'authentications.default.userid', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.API_PASSWORD, + id: 'authentications.default.password', + type: 'password', + required: true, + isPlaceholderInEditMode: true, + }, + ], + events: [ + { + label: FIELD_LABELS.TYPE, + id: 'event_stream_selection', + type: 'select', + required: false, + }, + ], + rsa_key_pair: [ + { + label: FIELD_LABELS.USERNAME, + id: 'authentications.ssh_keypair.userid', + type: 'text', + required: false, + }, + { + label: FIELD_LABELS.PRIVATE_KEY, + id: 'authentications.ssh_keypair.auth_key', + type: 'textarea', + required: false, + isPlaceholderInEditMode: true, + }, + ], + image_export: [ + { + label: FIELD_LABELS.POWERVC, + id: 'authentications.node.userid', + type: 'text', + required: false, + }, + { + label: FIELD_LABELS.ANSIBLE_ACCESS_METHOD, + id: 'authentications.node.options', + type: 'select', + required: false, + }, + { + label: FIELD_LABELS.POWERVC, + id: 'authentications.node.auth_key_password', + type: 'password', + required: false, + }, + { + label: FIELD_LABELS.POWERVC, + id: 'authentications.node.auth_key', + type: 'textarea', + required: false, + }, + ], + }, + formValues: { + default: { + uid_ems: FIELD_VALUES.DOMAIN_ID_DEFAULT, + 'endpoints.default.security_protocol': + SELECT_OPTIONS.SECURITY_PROTOCOL_SSL, + 'endpoints.default.port': FIELD_VALUES.PORT, + 'authentications.default.userid': FIELD_VALUES.USERNAME, + 'authentications.default.password': FIELD_VALUES.PASSWORD, + }, + }, + tabs: [ + TAB_LABELS.DEFAULT, + TAB_LABELS.EVENTS, + TAB_LABELS.RSA_KEY_PAIR, + TAB_LABELS.IMAGE_EXPORT, + ], + }); +} + +/** + * Creates an IBM Cloud Infrastructure Center provider configuration + * @returns {Object} - The provider configuration + */ +function getIBMCICProviderConfig() { + return createProviderConfig(PROVIDER_TYPES.IBM_CIC, { + formFields: { + default: [ + { + label: FIELD_LABELS.PROVIDER_REGION, + id: 'provider_region', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.API_VERSION, + id: 'api_version', + type: 'select', + required: true, + }, + { + label: FIELD_LABELS.DOMAIN_ID, + id: 'uid_ems', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.TENANT_MAPPING_ENABLED, + id: 'tenant_mapping_enabled', + type: 'checkbox', + required: false, + }, + { + label: FIELD_LABELS.SECURITY_PROTOCOL, + id: 'endpoints.default.security_protocol', + type: 'select', + required: true, + }, + { + label: FIELD_LABELS.HOSTNAME, + id: 'endpoints.default.hostname', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.API_PORT, + id: 'endpoints.default.port', + type: 'number', + required: true, + }, + { + label: FIELD_LABELS.USERNAME, + id: 'authentications.default.userid', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.PASSWORD, + id: 'authentications.default.password', + type: 'password', + required: true, + isPlaceholderInEditMode: true, + }, + { + label: FIELD_LABELS.TYPE, + id: 'event_stream_selection', + type: 'select', + required: false, + }, + { + label: FIELD_LABELS.HOSTNAME, + id: 'endpoints.amqp.hostname', + type: 'text', + required: false, + }, + { + label: FIELD_LABELS.API_PORT, + id: 'endpoints.amqp.port', + type: 'number', + required: false, + }, + { + label: FIELD_LABELS.USERNAME, + id: 'authentications.amqp.userid', + type: 'text', + required: false, + }, + { + label: FIELD_LABELS.PASSWORD, + id: 'authentications.amqp.password', + type: 'password', + required: false, + }, + { + label: FIELD_LABELS.USERNAME, + id: 'authentications.ssh_keypair.userid', + type: 'text', + required: false, + }, + { + label: FIELD_LABELS.PRIVATE_KEY, + id: 'authentications.ssh_keypair.auth_key', + type: 'textarea', + required: false, + isPlaceholderInEditMode: true, + }, + ], + }, + formValues: { + default: { + provider_region: FIELD_VALUES.PROVIDER_REGION, + api_version: SELECT_OPTIONS.API_VERSION_V3, + uid_ems: FIELD_VALUES.DOMAIN_ID_DEFAULT, + 'endpoints.default.security_protocol': + SELECT_OPTIONS.SECURITY_PROTOCOL_SSL, + 'endpoints.default.port': FIELD_VALUES.PORT, + 'authentications.default.userid': FIELD_VALUES.USERNAME, + 'authentications.default.password': FIELD_VALUES.PASSWORD, + }, + }, + // Values used for field selection that conditionally show other fields + fieldSelectionValues: { + default: { + api_version: SELECT_OPTIONS.API_VERSION_V3, + // TODO: set up multiple value validation + event_stream_selection: [ + SELECT_OPTIONS.EVENT_STREAM_TYPE_AMQP, + SELECT_OPTIONS.EVENT_STREAM_TYPE_STF, + ], + }, + }, + tabs: [TAB_LABELS.DEFAULT], + }); +} + +/** + * Creates an OpenStack provider configuration + * @returns {Object} - The provider configuration + */ +function getOpenStackProviderConfig() { + return createProviderConfig(PROVIDER_TYPES.OPENSTACK, { + formFields: { + default: [ + { + label: FIELD_LABELS.PROVIDER_REGION, + id: 'provider_region', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.OPENSTACK_INFRA_PROVIDER, + id: 'provider_id', + type: 'text', + required: false, + }, + { + label: FIELD_LABELS.API_VERSION, + id: 'api_version', + type: 'select', + required: true, + }, + { + label: FIELD_LABELS.DOMAIN_ID, + id: 'uid_ems', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.TENANT_MAPPING_ENABLED, + id: 'tenant_mapping_enabled', + type: 'checkbox', + required: false, + }, + { + label: FIELD_LABELS.SECURITY_PROTOCOL, + id: 'endpoints.default.security_protocol', + type: 'select', + required: true, + }, + { + label: FIELD_LABELS.HOSTNAME, + id: 'endpoints.default.hostname', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.API_PORT, + id: 'endpoints.default.port', + type: 'number', + required: true, + }, + { + label: FIELD_LABELS.USERNAME, + id: 'authentications.default.userid', + type: 'text', + required: true, + }, + { + label: FIELD_LABELS.PASSWORD, + id: 'authentications.default.password', + type: 'password', + required: true, + isPlaceholderInEditMode: true, + }, + { + label: FIELD_LABELS.TYPE, + id: 'event_stream_selection', + type: 'select', + required: false, + }, + { + label: FIELD_LABELS.HOSTNAME, + id: 'endpoints.amqp.hostname', + type: 'text', + required: false, + }, + { + label: FIELD_LABELS.API_PORT, + id: 'endpoints.amqp.port', + type: 'number', + required: false, + }, + { + label: FIELD_LABELS.USERNAME, + id: 'authentications.amqp.userid', + type: 'text', + required: false, + }, + { + label: FIELD_LABELS.PASSWORD, + id: 'authentications.amqp.password', + type: 'password', + required: false, + }, + { + label: FIELD_LABELS.USERNAME, + id: 'authentications.ssh_keypair.userid', + type: 'text', + required: false, + }, + { + label: FIELD_LABELS.PRIVATE_KEY, + id: 'authentications.ssh_keypair.auth_key', + type: 'textarea', + required: false, + isPlaceholderInEditMode: true, + }, + ], + }, + formValues: { + default: { + provider_region: FIELD_VALUES.PROVIDER_REGION, + api_version: SELECT_OPTIONS.API_VERSION_V3, + uid_ems: FIELD_VALUES.DOMAIN_ID_DEFAULT, + 'endpoints.default.security_protocol': + SELECT_OPTIONS.SECURITY_PROTOCOL_SSL, + 'endpoints.default.port': FIELD_VALUES.PORT, + 'authentications.default.userid': FIELD_VALUES.USERNAME, + 'authentications.default.password': FIELD_VALUES.PASSWORD, + }, + }, + // Values used for field selection that conditionally show other fields + fieldSelectionValues: { + default: { + api_version: SELECT_OPTIONS.API_VERSION_V3, + // TODO: set up multiple value validation + event_stream_selection: [ + SELECT_OPTIONS.EVENT_STREAM_TYPE_AMQP, + SELECT_OPTIONS.EVENT_STREAM_TYPE_STF, + ], + }, + }, + tabs: [TAB_LABELS.DEFAULT], + }); +} + +/** + * Provider Registry - Maps provider types to their factory functions + * This makes it easy to get a provider configuration by type + */ +const PROVIDER_REGISTRY = { + [PROVIDER_TYPES.VMWARE_VCLOUD]: getVMwareVcloudProviderConfig, + [PROVIDER_TYPES.ORACLE_CLOUD]: getOracleCloudProviderConfig, + [PROVIDER_TYPES.IBM_CLOUD_VPC]: getIBMCloudVPCProviderConfig, + [PROVIDER_TYPES.IBM_POWER_SYSTEMS]: getIBMPowerSystemsProviderConfig, + [PROVIDER_TYPES.GOOGLE_COMPUTE]: getGoogleComputeEngineProviderConfig, + [PROVIDER_TYPES.AZURE_STACK]: getAzureStackProviderConfig, + [PROVIDER_TYPES.AZURE]: getAzureProviderConfig, + [PROVIDER_TYPES.AMAZON_EC2]: getAmazonEC2ProviderConfig, + [PROVIDER_TYPES.IBM_POWERVC]: getIBMPowerVCProviderConfig, + [PROVIDER_TYPES.IBM_CIC]: getIBMCICProviderConfig, + [PROVIDER_TYPES.OPENSTACK]: getOpenStackProviderConfig, +}; + +/** + * Gets a provider configuration by type + * @param {string} type - The provider type + * @returns {Object} - The provider configuration + */ +export function getProviderConfig(type) { + if (!PROVIDER_REGISTRY[type]) { + cy.logAndThrowError(`Provider type "${type}" is not supported`); + } + return PROVIDER_REGISTRY[type](); +} diff --git a/cypress/support/commands/provider_helper_commands.js b/cypress/support/commands/provider_helper_commands.js new file mode 100644 index 00000000000..dee6e161bec --- /dev/null +++ b/cypress/support/commands/provider_helper_commands.js @@ -0,0 +1,890 @@ +import { + SELECT_OPTIONS, + TAB_LABELS, + FIELD_LABELS, + VALIDATION_MESSAGES, + PROVIDER_TYPES, + REGION_OPTIONS, + FLASH_MESSAGES, +} from '../../e2e/ui/Compute/Clouds/Providers/provider-factory'; +import { flashClassMap } from '../assertions/assertion_constants'; + +/** + * Generates a unique identifier using timestamp + * @returns {string} + */ +function generateUniqueIdentifier() { + return new Date().getTime(); +} + +/** + * Transforms any text string into a slug format using the given seperator('-', '_') + * @param {*} text + * @param {*} separator + * @example slugifyWith("Cloud Provider Name", "_") + * will return "cloud_provider_name" + */ +function slugifyWith(text, separator) { + return text.toLowerCase().replace(/\s+/g, separator); +} + +/** + * Fills common form fields that are present in all provider forms + * @param {Object} providerConfig - The provider configuration object + * @param {string} nameValue - The name to use for the provider + */ +Cypress.Commands.add('fillCommonFormFields', (providerConfig, nameValue) => { + cy.getFormSelectFieldById({ selectId: 'type' }).select(providerConfig.type); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); + cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( + SELECT_OPTIONS.ZONE_DEFAULT + ); +}); + +/** + * Fills form fields based on field definitions and values + * @param {Array} fields - Array of field definition objects + * @param {Object} values - Object containing field values + */ +Cypress.Commands.add('fillFormFields', (fields, values) => { + fields.forEach((field) => { + if (!values[field.id]) return; + + switch (field.type) { + case 'select': + cy.getFormSelectFieldById({ selectId: field.id }).select( + values[field.id] + ); + break; + case 'text': + cy.getFormInputFieldByIdAndType({ inputId: field.id }).type( + values[field.id] + ); + break; + case 'number': + cy.getFormInputFieldByIdAndType({ + inputId: field.id, + inputType: 'number', + }) + .clear() + .type(values[field.id]); + break; + case 'password': + cy.getFormInputFieldByIdAndType({ + inputId: field.id, + inputType: 'password', + }).type(values[field.id]); + break; + case 'textarea': + cy.getFormTextareaById({ textareaId: field.id }).type(values[field.id]); + break; + case 'checkbox': + if (values[field.id]) { + cy.getFormInputFieldByIdAndType({ + inputId: field.id, + inputType: 'checkbox', + }).check(); + } + break; + default: + break; + } + }); +}); + +/** + * Fills a provider form based on provider configuration + * @param {Object} providerConfig - The provider configuration object + * @param {string} nameValue - The name to use for the provider + * @param {string} hostValue - The hostname to use for the provider + */ +Cypress.Commands.add( + 'fillProviderForm', + (providerConfig, nameValue, hostValue) => { + cy.fillCommonFormFields(providerConfig, nameValue); + const defaultTabKey = slugifyWith(TAB_LABELS.DEFAULT, '_'); + const defaultTabFormFields = providerConfig.formFields[defaultTabKey]; + const defaultTabFormValues = providerConfig.formValues[defaultTabKey]; + if (defaultTabFormFields && defaultTabFormValues) { + cy.fillFormFields(defaultTabFormFields, defaultTabFormValues); + } + + // Since the host value needs to be unique per test, it's passed as a parameter instead of + // being hardcoded in the static formValues object. Only the default field is used(endpoints.default.hostname) + if (hostValue) { + const defaultHostFieldId = 'endpoints.default.hostname'; + const defaultHostFieldExists = providerConfig.formFields[ + defaultTabKey + ].find((fieldObject) => fieldObject.id === defaultHostFieldId); + if (defaultHostFieldExists) { + cy.getFormInputFieldByIdAndType({ + inputId: defaultHostFieldId, + }).type(hostValue); + } + } + } +); + +/** + * Validates common form fields that are present in all provider forms + * @param {boolean} isEdit - Whether the form is in edit mode + */ +Cypress.Commands.add('validateCommonFormFields', (providerType, isEdit) => { + cy.getFormLabelByForAttribute({ forValue: 'type' }) + .should('be.visible') + .and('contain.text', FIELD_LABELS.TYPE); + if (isEdit) { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.disabled') + .find('option:selected') + .should('have.text', providerType); + } else { + cy.getFormSelectFieldById({ selectId: 'type' }) + .should('be.visible') + .and('be.enabled') + .select(providerType); + } + cy.getFormLabelByForAttribute({ forValue: 'name' }) + .should('be.visible') + .and('contain.text', FIELD_LABELS.NAME); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }) + .should('be.visible') + .and('be.enabled'); + cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) + .should('be.visible') + .and('contain.text', FIELD_LABELS.ZONE); + cy.getFormSelectFieldById({ selectId: 'zone_id' }) + .should('be.visible') + .and('be.enabled'); +}); + +/** + * Validates form fields based on field definitions + * @param {Array} fields - Array of field definition objects + * @param {boolean} isEdit - Whether the form is in edit mode + */ +Cypress.Commands.add('validateFormFields', (fields, isEdit) => { + fields.forEach((field) => { + // Skip label validation for placeholder fields in edit mode + if (!(isEdit && field.isPlaceholderInEditMode)) { + cy.getFormLabelByForAttribute({ forValue: field.id }) + .scrollIntoView() + .should('be.visible') + .and('contain.text', field.label); + } + + switch (field.type) { + case 'select': + cy.getFormSelectFieldById({ selectId: field.id }) + .should('be.visible') + .and('be.enabled'); + break; + case 'text': + cy.getFormInputFieldByIdAndType({ inputId: field.id }) + .should('be.visible') + .and('be.enabled'); + break; + case 'number': + cy.getFormInputFieldByIdAndType({ + inputId: field.id, + inputType: 'number', + }) + .should('be.visible') + .and('be.enabled'); + break; + case 'password': + // Password fields appear as disabled placeholders in edit mode + // with a legend instead of a label, and have a different ID format + if (isEdit && field.isPlaceholderInEditMode) { + cy.getFormLegendByText({ legendText: field.label }); + cy.getFormInputFieldByIdAndType({ + inputId: `${field.id}-password-placeholder`, + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormInputFieldByIdAndType({ + inputId: field.id, + inputType: 'password', + }) + .should('be.visible') + .and('be.enabled'); + } + break; + case 'textarea': + // Similar to password fields, Auth key fields appear as disabled + // placeholders with a legend instead of a label + if (isEdit && field.isPlaceholderInEditMode) { + cy.getFormLegendByText({ legendText: field.label }); + cy.getFormInputFieldByIdAndType({ + inputId: `${field.id}-password-placeholder`, + inputType: 'password', + }) + .should('be.visible') + .and('be.disabled'); + } else { + cy.getFormTextareaById({ textareaId: field.id }) + .should('be.visible') + .and('be.enabled'); + } + break; + case 'checkbox': + cy.getFormInputFieldByIdAndType({ + inputId: field.id, + inputType: 'checkbox', + }) + .should('be.visible') + .and('be.enabled'); + break; + default: + break; + } + }); +}); + +/** + * Validates form buttons (validate, add/save, reset, cancel) + * @param {string} providerType - Type of provider to be validated + * @param {boolean} isEdit - Whether the form is in edit mode + */ +Cypress.Commands.add('validateFormButtons', (providerType, isEdit) => { + cy.contains('button', 'Validate') + .scrollIntoView() + .should('be.visible') + .and('be.disabled'); + // TODO: Confirm why the Save button for "IBM Cloud VPC" is enabled in edit mode even when no changes are made + const saveButtonAssertionText = + isEdit && providerType === PROVIDER_TYPES.IBM_CLOUD_VPC + ? 'be.enabled' + : 'be.disabled'; + cy.getFormFooterButtonByTypeWithText({ + buttonText: isEdit ? 'Save' : 'Add', + buttonType: 'submit', + }) + .should('be.visible') + .and(saveButtonAssertionText); + if (isEdit) { + const resetButtonEnabledProviderTypes = [ + PROVIDER_TYPES.VMWARE_VCLOUD, + PROVIDER_TYPES.IBM_CLOUD_VPC, + PROVIDER_TYPES.IBM_CIC, + PROVIDER_TYPES.OPENSTACK, + ]; + const resetButtonAssertionText = resetButtonEnabledProviderTypes.includes( + providerType + ) + ? 'be.enabled' + : 'be.disabled'; + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.visible') + .and(resetButtonAssertionText); + } + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) + .should('be.visible') + .and('be.enabled'); +}); + +/** + * Handles special tab setup requirements before validation + * Some tabs require selecting specific values in dropdowns before other fields become visible + * @param {string} tab - The tab name + * @param {Object} providerConfig - The provider configuration + */ +function setupTabForValidation(tab, providerConfig) { + if (tab === TAB_LABELS.DEFAULT) { + if (providerConfig.fieldSelectionValues.default) { + const eventStreamValues = + providerConfig.fieldSelectionValues.default.event_stream_selection; + cy.getFormSelectFieldById({ + selectId: 'api_version', + }).select(providerConfig.fieldSelectionValues.default.api_version); + cy.getFormSelectFieldById({ + selectId: 'event_stream_selection', + // TODO: Enhance to sequentially select values and validate their associated + // fields before moving to the next(like in IBM CIC & Openstack) + }).select(eventStreamValues[0]); + } + } else if (tab === TAB_LABELS.EVENTS) { + if (providerConfig.fieldSelectionValues.events) { + if (providerConfig.fieldSelectionValues.events.event_stream_selection) { + const eventStreamValues = + providerConfig.fieldSelectionValues.events.event_stream_selection; + cy.getFormSelectFieldById({ + selectId: 'event_stream_selection', + // TODO: Enhance to sequentially select values and validate their + // associated fields, if necessary in events tab + }).select(eventStreamValues[0]); + } else if (providerConfig.fieldSelectionValues.events.events_selection) { + cy.getFormSelectFieldById({ + selectId: 'events_selection', + }).select(providerConfig.fieldSelectionValues.events.events_selection); + } + } + } else if (tab === TAB_LABELS.METRICS) { + // For IBM Cloud VPC and other providers with metrics_selection + if (providerConfig.fieldSelectionValues.metrics) { + if (providerConfig.fieldSelectionValues.metrics.metrics_selection) { + cy.getFormSelectFieldById({ selectId: 'metrics_selection' }).select( + providerConfig.fieldSelectionValues.metrics.metrics_selection + ); + } + } + } +} + +/** + * Validates a provider form based on provider configuration + * @param {Object} providerConfig - The provider configuration object + * @param {boolean} isEdit - Whether the form is in edit mode + */ +Cypress.Commands.add('validateProviderForm', (providerConfig, isEdit) => { + cy.validateCommonFormFields(providerConfig.type, isEdit); + providerConfig.tabs.forEach((tab) => { + // If not on the default tab, switch to it + if (tab !== TAB_LABELS.DEFAULT) { + cy.tabs({ tabLabel: tab }); + } + // Set up the tab for validation (select required dropdown values) + setupTabForValidation(tab, providerConfig); + const tabKeyCorrespondingToTabName = slugifyWith(tab, '_'); + if (providerConfig.formFields[tabKeyCorrespondingToTabName]) { + cy.validateFormFields( + providerConfig.formFields[tabKeyCorrespondingToTabName], + isEdit + ); + } + }); + // Switch back to default tab + if (providerConfig.tabs.length > 1) { + cy.tabs({ tabLabel: TAB_LABELS.DEFAULT }); + } + cy.validateFormButtons(providerConfig.type, isEdit); +}); + +/** + * Updates provider fields for edit validation tests based on provider type + * @param {Object} providerType - The provider type + */ +Cypress.Commands.add('updateProviderFieldsForEdit', (providerType) => { + // Different providers need different fields updated for validation + switch (providerType) { + case PROVIDER_TYPES.VMWARE_VCLOUD: + cy.getFormSelectFieldById({ selectId: 'api_version' }).select( + SELECT_OPTIONS.API_VERSION_V9 + ); + break; + case PROVIDER_TYPES.ORACLE_CLOUD: + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTIONS.MELBOURNE + ); + break; + case PROVIDER_TYPES.IBM_CLOUD_VPC: + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTIONS.SPAIN + ); + break; + case PROVIDER_TYPES.IBM_POWER_SYSTEMS: + cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type('-xr4q'); + break; + case PROVIDER_TYPES.GOOGLE_COMPUTE: + cy.getFormInputFieldByIdAndType({ inputId: 'project' }).type('-76g1'); + break; + case PROVIDER_TYPES.AZURE_STACK: + case PROVIDER_TYPES.IBM_POWERVC: + case PROVIDER_TYPES.IBM_CIC: + case PROVIDER_TYPES.OPENSTACK: + cy.getFormSelectFieldById({ + selectId: 'endpoints.default.security_protocol', + }).select(SELECT_OPTIONS.SECURITY_PROTOCOL_NON_SSL); + break; + case PROVIDER_TYPES.AZURE: + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTIONS.CENTRAL_US + ); + break; + case PROVIDER_TYPES.AMAZON_EC2: + cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( + REGION_OPTIONS.ASIA_PACIFIC + ); + break; + default: + } +}); + +/** + * Selects a created provider from the data table + * @param {string} providerName - The name of the provider to select + */ +Cypress.Commands.add('selectCreatedProvider', (providerName) => { + // Set pagination to 200 items per page to include the target provider despite pending deletions + cy.get( + '.miq-fieldset-content .miq-pagination select#bx-pagination-select-1' + ).select('200'); + cy.selectTableRowsByText({ textArray: [providerName] }); +}); + +/** + * Intercepts the API call when adding a provider and handles special case for Azure Stack + * + * This command intercepts the POST request to '/api/providers' that occurs when adding a provider. + * For Azure Stack providers, it allows the request to reach the server (so data is created) but then + * overrides the response status code to 200 (OK). This is necessary because the server would normally + * return a 500 error when using mock values for fields like host, port, etc. in test environments. + * + * The command automatically triggers the form submission by clicking the 'Add' button. + * + * @param {Object} options - Options for the interception + * @param {boolean} [options.isAzureStack=false] - Whether the provider is Azure Stack, which requires + * special response handling + */ +Cypress.Commands.add( + 'interceptAddProviderApi', + ({ isAzureStack = false } = {}) => { + cy.interceptApi({ + alias: 'addProviderApi', + urlPattern: '/api/providers', + triggerFn: () => + cy + .getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }) + .click(), + ...(isAzureStack && { + responseInterceptor: (req) => { + // Let the request go through to the server(so that the data is created) and then override + // the response statusCode to 200, server will return internal_server_error(500) since we are + // using mock values for fields like host, port, etc. + req.continue((res) => { + res.send(200); + }); + }, + }), + }); + } +); + +/** + * Adds a provider and opens the edit form + * @param {Object} providerConfig - The provider configuration object + * @param {string} nameValue - The name to use for the provider + * @param {string} hostValue - The hostname to use for the provider (optional) + * @param {boolean} isAzureStack - Whether the provider is Azure Stack, which requires special handling when opening edit form + */ +Cypress.Commands.add( + 'addProviderAndOpenEditForm', + (providerConfig, nameValue, hostValue, isAzureStack) => { + cy.fillProviderForm(providerConfig, nameValue, hostValue); + cy.validate({ + stubErrorResponse: false, + }); + cy.interceptAddProviderApi({ isAzureStack }); + cy.selectCreatedProvider(nameValue); + // Azure-Stack needs to be handled differently, add similar cases if needed + // These APIs help populate the form fields + if (isAzureStack) { + // TODO: Switch to cy.interceptApi once its enhanced to support multiple api intercepts from a single event + cy.intercept( + 'GET', + /\/api\/providers\/(\d+)\?attributes=endpoints,authentications/, + (req) => { + const providerId = req.url.match(/\/api\/providers\/(\d+)\?/)[1]; + req.continue((res) => { + res.send(200, { + id: providerId, + type: 'ManageIQ::Providers::AzureStack::CloudManager', + name: nameValue, + zone_id: '2', + uid_ems: providerConfig.formValues.default.uid_ems, + subscription: providerConfig.formValues.default.subscription, + api_version: providerConfig.formValues.default.api_version, + endpoints: [ + { + role: 'default', + hostname: hostValue, + port: providerConfig.formValues.default[ + 'endpoints.default.port' + ], + security_protocol: + providerConfig.formValues.default[ + 'endpoints.default.security_protocol' + ], + }, + ], + authentications: [ + { + authtype: 'default', + userid: + providerConfig.formValues.default[ + 'authentications.default.userid' + ], + }, + ], + }); + }); + } + ).as('getProviderFieldValuesApi'); + cy.intercept( + 'GET', + '/api/zones?expand=resources&attributes=id,name,visible&filter[]=visible!=false&sort_by=name', + (req) => { + req.continue((res) => { + res.send(200, { + name: 'zones', + count: 2, + subcount: 1, + subquery_count: 1, + pages: 1, + resources: [ + { + href: 'http://localhost:3000/api/zones/2', + id: '2', + name: SELECT_OPTIONS.ZONE_DEFAULT, + visible: true, + }, + ], + }); + }); + } + ).as('getZoneDropdownOptionsApi'); + cy.toolbar('Configuration', 'Edit Selected Cloud Provider'); + cy.wait('@getProviderFieldValuesApi'); + cy.wait('@getZoneDropdownOptionsApi'); + } else { + cy.toolbar('Configuration', 'Edit Selected Cloud Provider'); + } + } +); + +/** + * Asserts validation failure message + */ +Cypress.Commands.add('assertValidationFailureMessage', () => { + cy.contains('.ddorg__carbon-error-helper-text', VALIDATION_MESSAGES.FAILED); +}); + +/** + * Asserts validation success message + */ +Cypress.Commands.add('assertValidationSuccessMessage', () => { + cy.contains('.bx--form__helper-text', VALIDATION_MESSAGES.SUCCESSFUL); +}); + +/** + * Asserts name already exists error + */ +Cypress.Commands.add('assertNameAlreadyExistsError', () => { + return cy.expect_inline_field_errors({ + containsText: VALIDATION_MESSAGES.NAME_ALREADY_EXISTS, + }); +}); + +/** + * Performs validation with optional error response stubbing + * @param {boolean} stubErrorResponse - Whether to stub an error response + * @param {string} errorMessage - The error message to show + */ +Cypress.Commands.add('validate', ({ stubErrorResponse, errorMessage }) => { + let response = { state: 'Finished', status: 'Error' }; + if (stubErrorResponse) { + response = { + ...response, + message: errorMessage, + }; + } else { + response = { ...response, status: 'Ok', task_results: {} }; + } + // not using cy.interceptApi because each validate call requires a fresh alias registration, + // reusing the same intercept callback results in it returning the first response object + cy.intercept('GET', '/api/tasks/*?attributes=task_results', response).as( + 'validateApi' + ); + cy.contains('button', 'Validate').click(); + cy.wait('@validateApi'); +}); + +/** + * Deletes a provider with optional flash message check + * @param {string} createdProviderName - The name of the provider to delete + * @param {boolean} assertDeleteFlashMessage - Whether to assert the delete flash message + */ +Cypress.Commands.add( + 'selectProviderAndDeleteWithOptionalFlashMessage', + ({ createdProviderName, assertDeleteFlashMessage }) => { + cy.selectCreatedProvider(createdProviderName); + cy.interceptApi({ + alias: 'deleteProviderApi', + urlPattern: '/ems_cloud/button?pressed=ems_cloud_delete', + triggerFn: () => + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => + cy.toolbar( + 'Configuration', + 'Remove Cloud Providers from Inventory' + ), + containsText: 'removed', + }), + onApiResponse: () => { + if (assertDeleteFlashMessage) { + cy.expect_flash(flashClassMap.success, 'delete'); + } + }, + }); + } +); + +/** + * Cleans up a provider by deleting it + * @param {string} createdProviderName - The name of the provider to clean up + */ +Cypress.Commands.add('cleanUp', ({ createdProviderName }) => { + cy.url() + .then((url) => { + // Navigate to cloud providers table view + if (!url.endsWith('/ems_cloud/show_list#/')) { + cy.visit('/ems_cloud/show_list#/'); + } + }) + .then(() => { + cy.selectProviderAndDeleteWithOptionalFlashMessage({ + createdProviderName, + assertDeleteFlashMessage: false, + }); + }); +}); + +/** + * Provider Test Generator helpers - Generates test cases for cloud providers + * These utilities make it easy to create test cases for different provider types + */ + +/** + * Generates a test suite for validating the add form of a provider + * @param {Object} providerConfig - The provider configuration object + */ +function generateAddFormValidationTests(providerConfig, isAzureStack = false) { + describe(`Validate ${providerConfig.type} add form`, () => { + it('Validate visibility of elements', () => { + cy.validateProviderForm(providerConfig, false); + }); + + it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { + cy.fillProviderForm( + providerConfig, + providerConfig.nameValue, + 'manageiq.example.com' + ); + cy.validate({ + stubErrorResponse: true, + errorMessage: providerConfig.validationError, + }); + cy.assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGES.OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + add/refresh/delete operations', () => { + /** + * The provider name is set in this variable to identify it for deletion + */ + const uniqueId = generateUniqueIdentifier(); + const nameValue = `${providerConfig.nameValue} - verify-validate-add-refresh-and-delete-operations - ${uniqueId}`; + const hostValue = `${slugifyWith( + providerConfig.type, + '-' + )}-${uniqueId}.com`; + cy.fillProviderForm(providerConfig, nameValue, hostValue); + //Add + cy.validate({ + stubErrorResponse: false, + }); + cy.assertValidationSuccessMessage(); + cy.interceptAddProviderApi({ isAzureStack }); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGES.OPERATION_SAVED); + // Refresh + cy.selectCreatedProvider(nameValue); + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => + cy.toolbar('Configuration', 'Refresh Relationships and Power States'), + containsText: FLASH_MESSAGES.REFRESH_OPERATION, + }); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGES.REFRESH_OPERATION); + // Delete + // FIXME: remove this block once bug is fixed + // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back + /* ==================================================================== */ + cy.toolbar('Configuration', 'Add a New Cloud Provider'); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); + /* ==================================================================== */ + cy.selectProviderAndDeleteWithOptionalFlashMessage({ + createdProviderName: nameValue, + assertDeleteFlashMessage: true, + }); + }); + }); +} + +/** + * Generates a test suite for validating the edit form of a provider + * @param {Object} providerConfig - The provider configuration object + * @param {boolean} isAzureStack - Whether the provider is Azure Stack (requires special handling) + */ +function generateEditFormValidationTests(providerConfig, isAzureStack = false) { + describe(`Validate ${providerConfig.type} edit form`, () => { + /** + * The provider name is set in this variable at the start of each test, + * allowing afterEach to identify it for deletion. + */ + let nameFieldValue; + let hostValue; + + it('Validate visibility of elements', () => { + const uniqueId = generateUniqueIdentifier(); + nameFieldValue = `${providerConfig.nameValue} - verify-edit-form-elements - ${uniqueId}`; + hostValue = `${slugifyWith(providerConfig.type, '-')}-${uniqueId}.com`; + cy.addProviderAndOpenEditForm( + providerConfig, + nameFieldValue, + hostValue, + isAzureStack + ); + cy.validateProviderForm(providerConfig, true); + }); + + it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { + const uniqueId = generateUniqueIdentifier(); + nameFieldValue = `${providerConfig.nameValue} - verify-edit-form-validation-error - ${uniqueId}`; + hostValue = `${slugifyWith(providerConfig.type, '-')}-${uniqueId}.com`; + cy.addProviderAndOpenEditForm( + providerConfig, + nameFieldValue, + hostValue, + isAzureStack + ); + cy.updateProviderFieldsForEdit(providerConfig.type); + cy.validate({ + stubErrorResponse: true, + errorMessage: providerConfig.validationError, + }); + cy.assertValidationFailureMessage(); + cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) + .should('be.enabled') + .click(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Cancel', + }).click(); + cy.expect_flash( + flashClassMap.success, + FLASH_MESSAGES.OPERATION_CANCELLED + ); + }); + + it('Verify successful validate + edit operation', () => { + const uniqueId = generateUniqueIdentifier(); + nameFieldValue = `${providerConfig.nameValue} - verify-validate-and-edit-operations - ${uniqueId}`; + hostValue = `${slugifyWith(providerConfig.type, '-')}-${uniqueId}.com`; + cy.addProviderAndOpenEditForm( + providerConfig, + nameFieldValue, + hostValue, + isAzureStack + ); + // Update fields based on provider type + cy.updateProviderFieldsForEdit(providerConfig.type); + cy.validate({ + stubErrorResponse: false, + }); + cy.assertValidationSuccessMessage(); + // Azure Stack needs to be handled differently, add similar cases if needed + if (isAzureStack) { + cy.interceptApi({ + method: 'PATCH', + alias: 'editAzureStackProviderApi', + urlPattern: /\/api\/providers\/\d+/, + triggerFn: () => + cy + .getFormFooterButtonByTypeWithText({ + buttonText: 'Save', + buttonType: 'submit', + }) + .should('be.enabled') + .click(), + responseInterceptor: (req) => { + req.continue((res) => { + res.send(200); + }); + }, + }); + } else { + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Save', + buttonType: 'submit', + }) + .should('be.enabled') + .click(); + } + cy.expect_flash(flashClassMap.success, FLASH_MESSAGES.OPERATION_SAVED); + }); + + afterEach(() => { + cy.cleanUp({ createdProviderName: nameFieldValue }); + }); + }); +} + +/** + * Generates a test suite for validating the name uniqueness of a provider + * @param {Object} providerConfig - The provider configuration object + * @param {boolean} isAzureStack - Whether the provider is Azure Stack (requires special handling) + */ +function generateNameUniquenessTests(providerConfig, isAzureStack = false) { + describe(`${providerConfig.type} provider name uniqueness validation`, () => { + /** + * The provider name is set in this variable at the start of the test, allowing afterEach to identify it for deletion. + */ + let nameFieldValue; + let hostValue; + + beforeEach(() => { + const uniqueId = generateUniqueIdentifier(); + nameFieldValue = `${providerConfig.nameValue} - verify-duplicate-restriction - ${uniqueId}`; + hostValue = `${slugifyWith(providerConfig.type, '-')}-${uniqueId}.com`; + + cy.fillProviderForm(providerConfig, nameFieldValue, hostValue); + cy.validate({ + stubErrorResponse: false, + }); + cy.interceptAddProviderApi({ isAzureStack }); + }); + + it('Should display error on duplicate name usage', () => { + cy.toolbar('Configuration', 'Add a New Cloud Provider'); + // Add same name as above + cy.fillProviderForm(providerConfig, nameFieldValue, hostValue); + cy.assertNameAlreadyExistsError(); + }); + + afterEach(() => { + cy.cleanUp({ createdProviderName: nameFieldValue }); + }); + }); +} + +/** + * Generates all test suites for a provider + * @param {Object} providerConfig - The provider configuration object + */ +export function generateProviderTests(providerConfig) { + const isAzureStack = providerConfig.type === PROVIDER_TYPES.AZURE_STACK; + + describe(`Validate cloud provider type: ${providerConfig.type}`, () => { + generateAddFormValidationTests(providerConfig, isAzureStack); + generateEditFormValidationTests(providerConfig, isAzureStack); + generateNameUniquenessTests(providerConfig, isAzureStack); + }); +} diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js index 4a1915269d6..26870d17a51 100644 --- a/cypress/support/e2e.js +++ b/cypress/support/e2e.js @@ -50,6 +50,7 @@ import './commands/gtl.js'; import './commands/login.js'; import './commands/menu.js'; import './commands/miq_data_table_commands.js'; +import './commands/provider_helper_commands.js'; import './commands/select.js'; import './commands/stub_notifications.js'; import './commands/tabs.js'; From 37e1c17278ca442f29d245a1bd9f77a631bea255 Mon Sep 17 00:00:00 2001 From: asirvadAbrahamVarghese Date: Tue, 7 Oct 2025 11:22:06 +0530 Subject: [PATCH 3/4] Refactored into a pluggable design --- .../Clouds/Providers/cloud_provider.cy.js | 4343 +---------------- 1 file changed, 39 insertions(+), 4304 deletions(-) diff --git a/cypress/e2e/ui/Compute/Clouds/Providers/cloud_provider.cy.js b/cypress/e2e/ui/Compute/Clouds/Providers/cloud_provider.cy.js index 0d5566ca323..9b879d45ff8 100644 --- a/cypress/e2e/ui/Compute/Clouds/Providers/cloud_provider.cy.js +++ b/cypress/e2e/ui/Compute/Clouds/Providers/cloud_provider.cy.js @@ -1,4322 +1,57 @@ /* eslint-disable no-undef */ -import { flashClassMap } from '../../../../../support/assertions/assertion_constants'; - -// Menu options -const COMPUTE_MENU_OPTION = 'Compute'; -const CLOUDS_AUTOMATION_MENU_OPTION = 'Clouds'; -const PROVIDERS_MENU_OPTION = 'Providers'; - -// Data table component URL -const CLOUD_PROVIDERS_LIST_URL = '/ems_cloud/show_list#/'; - -// Config options -const CONFIG_TOOLBAR_BUTTON = 'Configuration'; -const ADD_PROVIDER_CONFIG_OPTION = 'Add a New Cloud Provider'; -const EDIT_PROVIDER_CONFIG_OPTION = 'Edit Selected Cloud Provider'; -const REMOVE_PROVIDER_CONFIG_OPTION = 'Remove Cloud Providers from Inventory'; -const REFRESH_CONFIG_OPTION = 'Refresh Relationships and Power States'; - -// Provider types -const PROVIDER_TYPE_VMWARE_VCLOUD = 'VMware vCloud'; -const PROVIDER_TYPE_AZURE_STACK = 'Azure Stack'; -const PROVIDER_TYPE_IBM_CLOUD_VPC = 'IBM Cloud VPC'; -const PROVIDER_TYPE_IBM_POWER_SYSTEMS = 'IBM Power Systems Virtual Servers'; -const PROVIDER_TYPE_GOOGLE_COMPUTE = 'Google Compute Engine'; -const PROVIDER_TYPE_ORACLE_CLOUD = 'Oracle Cloud'; -const PROVIDER_TYPE_AZURE = 'Azure'; -const PROVIDER_TYPE_AMAZON_EC2 = 'Amazon EC2'; -const PROVIDER_TYPE_IBM_POWERVC = 'IBM PowerVC'; -const PROVIDER_TYPE_IBM_CIC = 'IBM Cloud Infrastructure Center'; -const PROVIDER_TYPE_OPENSTACK = 'OpenStack'; - -// Other select options -const EVENT_STREAM_TYPE_AMQP = 'AMQP'; -const EVENT_STREAM_TYPE_STF = 'STF'; -const ENABLED_SELECT_OPTION = 'Enabled'; -const API_VERSION_TYPE_V3 = 'Keystone V3'; -const API_VERSION_TYPE_V5 = 'vCloud API 5.5'; -const API_VERSION_TYPE_V9 = 'vCloud API 9.0'; -const API_VERSION_TYPE_2017 = 'V2017_03_09'; -const ZONE_OPTION_DEFAULT = 'default'; -const REGION_OPTION_CENTRAL_INDIA = 'Central India'; -const REGION_OPTION_CENTRAL_US = 'Central US'; -const REGION_OPTION_HYDERABAD = 'ap-hyderabad-1'; -const REGION_OPTION_MELBOURNE = 'ap-melbourne-1'; -const REGION_OPTION_AUSTRALIA = 'Australia (Sydney)'; -const REGION_OPTION_SPAIN = 'EU Spain (Madrid)'; -const REGION_OPTION_CANADA = 'Canada (Central)'; -const REGION_OPTION_ASIA_PACIFIC = 'Asia Pacific (Malaysia)'; -const SECURITY_PROTOCOL_SSL = 'SSL'; -const SECURITY_PROTOCOL_NON_SSL = 'Non-SSL'; - -// Field labels -const TYPE_FIELD_LABEL = 'Type'; -const NAME_FIELD_LABEL = 'Name'; -const ZONE_FIELD_LABEL = 'Zone'; -const API_VERSION_FIELD_LABEL = 'API Version'; -const HOSTNAME_FIELD_LABEL = 'Hostname (or IPv4 or IPv6 address)'; -const API_PORT_FIELD_LABEL = 'API Port'; -const USERNAME_FIELD_LABEL = 'Username'; -const PASSWORD_FIELD_LABEL = 'Password'; -const SECURITY_PROTOCOL_FIELD_LABEL = 'Security Protocol'; -const REGION_FIELD_LABEL = 'Region'; -const TENANT_ID_FIELD_LABEL = 'Tenant ID'; -const DOMAIN_ID_FIELD_LABEL = 'Domain ID'; -const USER_ID_FIELD_LABEL = 'User ID'; -const PUBLIC_KEY_FIELD_LABEL = 'Public Key'; -const PRIVATE_KEY_FIELD_LABEL = 'Private Key'; -const IBM_CLOUD_COMMON_FIELD_LABEL = 'IBM Cloud'; -const SERVICE_COMMON_FIELD_LABEL = 'Service'; -const PROJECT_ID_FIELD_LABEL = 'Project ID'; -const SUBSCRIPTION_ID_FIELD_LABEL = 'Subscription ID'; -const ENDPOINT_URL_FIELD_LABEL = 'Endpoint URL'; -const CLIENT_ID_FIELD_LABEL = 'Client ID'; -const CLIENT_KEY_FIELD_LABEL = 'Client Key'; -const ASSUME_ROLE_ARN_FIELD_LABEL = 'Assume role ARN'; -const ACCESS_KEY_ID_FIELD_LABEL = 'Access Key ID'; -const SECRET_ACCESS_KEY_FIELD_LABEL = 'Secret Access Key'; -const SMARTSTATE_DOCKER_TAB_LABEL = 'SmartState Docker'; -const PROVIDER_REGION_FIELD_LABEL = 'Provider Region'; -const OPENSTACK_INFRA_PROVIDER_FIELD_LABEL = 'Openstack Infra Provider'; -const POWERVC_API_ENDPOINT_FIELD_LABEL = - 'PowerVC API Endpoint (Hostname or IPv4/IPv6 address)'; -const ANSIBLE_ACCESS_METHOD_FIELD_LABEL = 'Ansible Access Method'; -const TENANT_MAPPING_ENABLED_FIELD_LABEL = 'Tenant Mapping Enabled'; -const API_USERNAME_FIELD_LABEL = 'API Username'; -const API_PASSWORD_FIELD_LABEL = 'API Password'; -const POWERVC_COMMON_FIELD_LABEL = 'PowerVC'; - -// Tab labels -const EVENTS_TAB_LABEL = 'Events'; -const METRICS_TAB_LABEL = 'Metrics'; -const RSA_KEY_PAIR_TAB_LABEL = 'RSA key pair'; -const IMAGE_EXPORT_TAB_LABEL = 'Image Export'; - -// Field values -const TEST_NAME = 'Test Name:'; -const AZURE_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_AZURE}`; -const VMWARE_VCLOUD_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_VMWARE_VCLOUD}`; -const ORACLE_CLOUD_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_ORACLE_CLOUD}`; -const IBM_CLOUD_VPC_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_IBM_CLOUD_VPC}`; -const IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_IBM_POWER_SYSTEMS}`; -const GOOGLE_COMPUTE_ENGINE_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_GOOGLE_COMPUTE}`; -const AZURE_STACK_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_AZURE_STACK}`; -const AMAZON_EC2_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_AMAZON_EC2}`; -const IBM_POWERVC_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_IBM_POWERVC}`; -const IBM_CIC_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_IBM_CIC}`; -const OPENSTACK_NAME_VALUE = `${TEST_NAME} ${PROVIDER_TYPE_OPENSTACK}`; -const TENANT_ID_VALUE = '101'; -const SUBSCRIPTION_ID_VALUE = 'z565815f-05b6-402f-1999-045155da7dq4'; -const ENDPOINT_URL_VALUE = '/api'; -const CLIENT_ID_VALUE = 'manageiq.example.com'; -const CLIENT_KEY_VALUE = 'test_client_key'; -const PORT_VALUE = '3000'; -const USERNAME_VALUE = 'admin@example.com'; -const PASSWORD_VALUE = 'password123'; -const PRIVATE_KEY_VALUE = - '-----BEGIN PRIVATE KEY-----\nMIIEvQIBAzApPugkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC\n-----END PRIVATE KEY-----'; -const PUBLIC_KEY_VALUE = - '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAz14iAAOCAQ8AMIIBCgKCAQEA\n-----END PUBLIC KEY-----'; -const CLOUD_API_KEY_VALUE = 'ibm_cloud_api_key_k#157'; -const GUID_VALUE = '723e4a67-e89b-1qd3-z486-920614074000'; -const PROJECT_ID_VALUE = 'gcp-project-123456'; -const ASSUME_ROLE_VALUE = 'arn:aws:iam::123456789012:role/ManageIQRole'; -const ACCESS_KEY_ID_VALUE = 'AKIAIOSFODNN7EXAMPLE'; -const SECRET_ACCESS_KEY_VALUE = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'; -const DOMAIN_ID_DEFAULT_VALUE = 'default'; -const PROVIDER_REGION_VALUE = 'RegionOne'; - -// Flash message text snippets -const FLASH_MESSAGE_OPERATION_CANCELLED = 'cancelled'; -const FLASH_MESSAGE_OPERATION_SAVED = 'saved'; -const FLASH_MESSAGE_DELETE_OPERATION = 'delete'; -const REFRESH_OPERATION_MESSAGE = 'Refresh'; -const REMOVE_PROVIDER_BROWSER_ALERT_MESSAGE = 'removed'; - -// Other message snippets -const VALIDATION_FAILED_COMMON_ERROR = 'Validation failed'; -const VALIDATION_SUCCESSFUL_COMMON_MESSAGE = 'Validation successful'; -const IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_VALIDATION_ERROR = - 'IAM authentication failed'; -const VMWARE_VCLOUD_VALIDATION_ERROR = - 'Socket error: no address for example.manageiq.com'; -const ORACLE_CLOUD_VALIDATION_ERROR = 'The format of tenancy is invalid.'; -const IBM_CLOUD_VPC_VALIDATION_ERROR = 'Provided API key could not be found.'; -const GOOGLE_COMPUTE_ENGINE_VALIDATION_ERROR = 'Invalid Google JSON key'; -const AZURE_STACK_VALIDATION_ERROR = - 'Failed to open TCP connection to example.manageiq.com:3000'; -const AZURE_VALIDATION_ERROR = - 'Incorrect credentials - no host component for URI'; -const AMAZON_EC2_VALIDATION_ERROR = - 'The security token included in the request is invalid.'; -const IBM_POWERVC_VALIDATION_ERROR = - 'unable to retrieve IBM PowerVC release version number'; -const IBM_CIC_VALIDATION_ERROR = 'Login attempt timed out'; -const OPENSTACK_VALIDATION_ERROR = - 'Socket error: no address for example.manageiq.com'; -const NAME_ALRADY_EXISTS_ERROR = 'already exists'; - -// Methods for VMware vCloud -function validateVmwareVcloudFormFields(isEdit) { - cy.getFormLabelByForAttribute({ forValue: 'type' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - if (isEdit) { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.disabled') - .find('option:selected') - .should('have.text', PROVIDER_TYPE_VMWARE_VCLOUD); - } else { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.enabled') - .select(PROVIDER_TYPE_VMWARE_VCLOUD); - } - cy.getFormLabelByForAttribute({ forValue: 'name' }) - .should('be.visible') - .and('contain.text', NAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) - .should('be.visible') - .and('contain.text', ZONE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'zone_id' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'api_version' }) - .should('be.visible') - .and('contain.text', API_VERSION_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'api_version' }) - .should('be.visible') - .and('be.enabled'); - cy.contains('h3', 'Endpoints').should('be.visible'); - /* Verify Default tab fields */ - cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.hostname' }) - .should('be.visible') - .and('contain.text', HOSTNAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.hostname' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.port' }) - .should('be.visible') - .and('contain.text', API_PORT_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.port', - inputType: 'number', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.userid', - }) - .should('be.visible') - .and('contain.text', USERNAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }) - .should('be.visible') - .and('be.enabled'); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', PASSWORD_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.password', - }) - .scrollIntoView() - .should('be.visible') - .and('contain.text', PASSWORD_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password-password-placeholder', - inputType: 'password', - }) - .scrollIntoView() - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - } - cy.contains('#default-tab__panel button', 'Validate') - .should('be.visible') - .and('be.disabled'); - cy.tabs({ tabLabel: EVENTS_TAB_LABEL }); - cy.getFormLabelByForAttribute({ forValue: 'event_stream_selection' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'event_stream_selection' }) - .should('be.visible') - .and('be.enabled') - .select(EVENT_STREAM_TYPE_AMQP); - cy.getFormLabelByForAttribute({ - forValue: 'endpoints.amqp.security_protocol', - }) - .should('be.visible') - .and('contain.text', SECURITY_PROTOCOL_FIELD_LABEL); - cy.getFormSelectFieldById({ - selectId: 'endpoints.amqp.security_protocol', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.amqp.hostname' }) - .should('be.visible') - .and('contain.text', HOSTNAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.amqp.hostname' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.amqp.port' }) - .scrollIntoView() - .should('be.visible') - .and('contain.text', API_PORT_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.amqp.port', - inputType: 'number', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'authentications.amqp.userid' }) - .should('be.visible') - .and('contain.text', USERNAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.amqp.userid', - }) - .should('be.visible') - .and('be.enabled'); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', PASSWORD_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.amqp.password', - }) - .should('be.visible') - .and('contain.text', PASSWORD_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.amqp.password-password-placeholder', - inputType: 'password', - }) - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.amqp.password', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - } - cy.contains('#events-tab__panel button', 'Validate') - .should('be.visible') - .and('be.disabled'); - cy.getFormFooterButtonByTypeWithText({ - buttonText: isEdit ? 'Save' : 'Add', - buttonType: 'submit', - }) - .should('be.visible') - .and('be.disabled'); - if (isEdit) { - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.visible') - .and('be.enabled'); - } - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) - .should('be.visible') - .and('be.enabled'); -} - -function fillVmwareVcloudForm({ nameValue, hostValue }) { - cy.getFormSelectFieldById({ selectId: 'type' }).select( - PROVIDER_TYPE_VMWARE_VCLOUD - ); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); - cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( - ZONE_OPTION_DEFAULT - ); - cy.getFormSelectFieldById({ selectId: 'api_version' }).select( - API_VERSION_TYPE_V5 - ); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.hostname', - }).type(hostValue); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.port', - inputType: 'number', - }) - .clear() - .type(PORT_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }).type(USERNAME_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password', - inputType: 'password', - }).type(PASSWORD_VALUE); -} - -function addVmwareVcloudProviderAndOpenEditForm({ nameValue, hostValue }) { - fillVmwareVcloudForm({ - nameValue, - hostValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - selectCreatedProvider(nameValue); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); -} - -// Methods for Oracle Cloud -function validateOracleCloudFormFields(isEdit) { - cy.getFormLabelByForAttribute({ forValue: 'type' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - if (isEdit) { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.disabled') - .find('option:selected') - .should('have.text', PROVIDER_TYPE_ORACLE_CLOUD); - } else { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.enabled') - .select(PROVIDER_TYPE_ORACLE_CLOUD); - } - cy.getFormLabelByForAttribute({ forValue: 'name' }) - .should('be.visible') - .and('contain.text', NAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) - .should('be.visible') - .and('contain.text', ZONE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'zone_id' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'provider_region' }) - .should('be.visible') - .and('contain.text', REGION_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'provider_region' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'uid_ems' }) - .should('be.visible') - .and('contain.text', TENANT_ID_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }) - .should('be.visible') - .and('be.enabled'); - cy.contains('h3', 'Endpoints').should('be.visible'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.userid', - }) - .should('be.visible') - .and('contain.text', USER_ID_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }) - .should('be.visible') - .and('be.enabled'); - cy.get('[id="authentications.default.userid-helper-text"]').contains( - 'privileged access' - ); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', PRIVATE_KEY_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.auth_key', - }) - .should('be.visible') - .and('contain.text', PRIVATE_KEY_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.auth_key-password-placeholder', - inputType: 'password', - }) - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormTextareaById({ textareaId: 'authentications.default.auth_key' }) - .should('be.visible') - .and('be.enabled'); - } - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.public_key', - }) - .scrollIntoView() - .should('be.visible') - .and('contain.text', PUBLIC_KEY_FIELD_LABEL); - cy.getFormTextareaById({ - textareaId: 'authentications.default.public_key', - }) - .should('be.visible') - .and('be.enabled'); - cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); - cy.getFormFooterButtonByTypeWithText({ - buttonText: isEdit ? 'Save' : 'Add', - buttonType: 'submit', - }) - .should('be.visible') - .and('be.disabled'); - if (isEdit) { - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.visible') - .and('be.disabled'); - } - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) - .should('be.visible') - .and('be.enabled'); -} - -function fillOracleCloudForm({ nameValue }) { - cy.getFormSelectFieldById({ selectId: 'type' }).select( - PROVIDER_TYPE_ORACLE_CLOUD - ); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); - cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( - ZONE_OPTION_DEFAULT - ); - cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( - REGION_OPTION_HYDERABAD - ); - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type(TENANT_ID_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }).type(USERNAME_VALUE); - cy.getFormTextareaById({ - textareaId: 'authentications.default.auth_key', - }).type(PRIVATE_KEY_VALUE); - cy.getFormTextareaById({ - textareaId: 'authentications.default.public_key', - }).type(PUBLIC_KEY_VALUE); -} - -function addOracleCloudProviderAndOpenEditForm({ nameValue }) { - fillOracleCloudForm({ - nameValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - selectCreatedProvider(nameValue); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); -} - -// Methods for IBM Cloud VPC -function validateIbmCloudVpcFormFields(isEdit) { - cy.getFormLabelByForAttribute({ forValue: 'type' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - if (isEdit) { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.disabled') - .find('option:selected') - .should('have.text', PROVIDER_TYPE_IBM_CLOUD_VPC); - } else { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.enabled') - .select(PROVIDER_TYPE_IBM_CLOUD_VPC); - } - cy.getFormLabelByForAttribute({ forValue: 'name' }) - .should('be.visible') - .and('contain.text', NAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) - .should('be.visible') - .and('contain.text', ZONE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'zone_id' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'provider_region' }) - .should('be.visible') - .and('contain.text', REGION_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'provider_region' }) - .should('be.visible') - .and('be.enabled'); - cy.contains('h3', 'Endpoint').should('be.visible'); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', IBM_CLOUD_COMMON_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.auth_key', - }) - .should('be.visible') - .and('contain.text', IBM_CLOUD_COMMON_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.auth_key-password-placeholder', - inputType: 'password', - }) - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.auth_key', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - } - cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); - cy.tabs({ tabLabel: METRICS_TAB_LABEL }); - cy.getFormLabelByForAttribute({ forValue: 'metrics_selection' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'metrics_selection' }) - .should('be.visible') - .and('be.enabled') - .select(ENABLED_SELECT_OPTION); - cy.getFormLabelByForAttribute({ - forValue: 'endpoints.metrics.options.monitoring_instance_id', - }) - .should('be.visible') - .and('contain.text', IBM_CLOUD_COMMON_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.metrics.options.monitoring_instance_id', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - cy.tabs({ tabLabel: EVENTS_TAB_LABEL }); - cy.getFormLabelByForAttribute({ forValue: 'events_selection' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'events_selection' }) - .should('be.visible') - .and('be.enabled') - .select(ENABLED_SELECT_OPTION); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.events.auth_key', - }) - .should('be.visible') - .and('contain.text', IBM_CLOUD_COMMON_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.events.auth_key', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - if (isEdit) { - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Save', - buttonType: 'submit', - }) - .should('be.visible') - .and('be.enabled'); - } else { - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }) - .should('be.visible') - .and('be.disabled'); - } - if (isEdit) { - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.visible') - .and('be.enabled'); - } - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) - .should('be.visible') - .and('be.enabled'); -} - -function fillIbmCloudVpcForm({ nameValue }) { - cy.getFormSelectFieldById({ selectId: 'type' }).select( - PROVIDER_TYPE_IBM_CLOUD_VPC - ); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); - cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( - ZONE_OPTION_DEFAULT - ); - cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( - REGION_OPTION_AUSTRALIA - ); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.auth_key', - inputType: 'password', - }).type(CLOUD_API_KEY_VALUE); -} - -function addIbmCloudVpcProviderAndOpenEditForm({ nameValue }) { - fillIbmCloudVpcForm({ - nameValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - selectCreatedProvider(nameValue); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); -} - -// Methods for IBM Power Systems Virtual Servers -function validateIbmPowerSystemsVirtualServersFormFields(isEdit) { - cy.getFormLabelByForAttribute({ forValue: 'type' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - if (isEdit) { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.disabled') - .find('option:selected') - .should('have.text', PROVIDER_TYPE_IBM_POWER_SYSTEMS); - } else { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.enabled') - .select(PROVIDER_TYPE_IBM_POWER_SYSTEMS); - } - cy.getFormLabelByForAttribute({ forValue: 'name' }) - .should('be.visible') - .and('contain.text', NAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) - .should('be.visible') - .and('contain.text', ZONE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'zone_id' }) - .should('be.visible') - .and('be.enabled'); - cy.contains('h3', 'Endpoints').should('be.visible'); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', IBM_CLOUD_COMMON_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.auth_key', - }) - .should('be.visible') - .and('contain.text', IBM_CLOUD_COMMON_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.auth_key-password-placeholder', - inputType: 'password', - }) - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.auth_key', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - } - cy.getFormLabelByForAttribute({ forValue: 'uid_ems' }) - .should('be.visible') - .and('contain.text', SERVICE_COMMON_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }) - .should('be.visible') - .and('be.enabled'); - cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); - cy.getFormFooterButtonByTypeWithText({ - buttonText: isEdit ? 'Save' : 'Add', - buttonType: 'submit', - }) - .scrollIntoView() - .should('be.visible') - .and('be.disabled'); - if (isEdit) { - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.visible') - .and('be.disabled'); - } - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) - .should('be.visible') - .and('be.enabled'); -} - -function fillIbmPowerSystemsVirtualServersForm({ nameValue }) { - cy.getFormSelectFieldById({ selectId: 'type' }).select( - PROVIDER_TYPE_IBM_POWER_SYSTEMS - ); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); - cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( - ZONE_OPTION_DEFAULT - ); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.auth_key', - inputType: 'password', - }).type(CLOUD_API_KEY_VALUE); - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type(GUID_VALUE); -} - -function addIbmPowerSystemsVirtualServersProviderAndOpenEditForm({ - nameValue, -}) { - fillIbmPowerSystemsVirtualServersForm({ - nameValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - selectCreatedProvider(nameValue); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); -} - -// Methods for Google Compute Engine -function validateGoogleComputeEngineFormFields(isEdit) { - cy.getFormLabelByForAttribute({ forValue: 'type' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - if (isEdit) { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.disabled') - .find('option:selected') - .should('have.text', PROVIDER_TYPE_GOOGLE_COMPUTE); - } else { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.enabled') - .select(PROVIDER_TYPE_GOOGLE_COMPUTE); - } - cy.getFormLabelByForAttribute({ forValue: 'name' }) - .should('be.visible') - .and('contain.text', NAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) - .should('be.visible') - .and('contain.text', ZONE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'zone_id' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'project' }) - .should('be.visible') - .and('contain.text', PROJECT_ID_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'project' }) - .should('be.visible') - .and('be.enabled'); - cy.contains('h3', 'Endpoint').should('be.visible'); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', SERVICE_COMMON_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.auth_key', - }) - .should('be.visible') - .and('contain.text', SERVICE_COMMON_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.auth_key-password-placeholder', - inputType: 'password', - }) - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormTextareaById({ textareaId: 'authentications.default.auth_key' }) - .should('be.visible') - .and('be.enabled'); - } - cy.contains('button', 'Validate') - .scrollIntoView() - .should('be.visible') - .and('be.disabled'); - cy.getFormFooterButtonByTypeWithText({ - buttonText: isEdit ? 'Save' : 'Add', - buttonType: 'submit', - }) - .should('be.visible') - .and('be.disabled'); - if (isEdit) { - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.visible') - .and('be.disabled'); - } - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) - .should('be.visible') - .and('be.enabled'); -} - -function fillGoogleComputeEngineForm({ nameValue }) { - cy.getFormSelectFieldById({ selectId: 'type' }).select( - PROVIDER_TYPE_GOOGLE_COMPUTE - ); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); - cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( - ZONE_OPTION_DEFAULT - ); - cy.getFormInputFieldByIdAndType({ inputId: 'project' }).type( - PROJECT_ID_VALUE - ); - cy.getFormTextareaById({ - textareaId: 'authentications.default.auth_key', - }).type( - `{"type":"service_account","project_id":"${PROJECT_ID_VALUE}","private_key":"${PRIVATE_KEY_VALUE}"}` - ); -} - -function addGoogleComputeEngineProviderAndOpenEditForm({ nameValue }) { - fillGoogleComputeEngineForm({ - nameValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - selectCreatedProvider(nameValue); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); -} - -// Methods for Azure Stack -function validateAzureStackFormFields(isEdit) { - cy.getFormLabelByForAttribute({ forValue: 'type' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - if (isEdit) { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.disabled') - .find('option:selected') - .should('have.text', PROVIDER_TYPE_AZURE_STACK); - } else { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.enabled') - .select(PROVIDER_TYPE_AZURE_STACK); - } - cy.getFormLabelByForAttribute({ forValue: 'name' }) - .should('be.visible') - .and('contain.text', NAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) - .should('be.visible') - .and('contain.text', ZONE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'zone_id' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'uid_ems' }) - .should('be.visible') - .and('contain.text', TENANT_ID_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'subscription' }) - .should('be.visible') - .and('contain.text', SUBSCRIPTION_ID_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'subscription' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'api_version' }) - .should('be.visible') - .and('contain.text', API_VERSION_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'api_version' }) - .should('be.visible') - .and('be.enabled'); - cy.contains('h3', 'Endpoint').should('be.visible'); - cy.getFormLabelByForAttribute({ - forValue: 'endpoints.default.security_protocol', - }) - .should('be.visible') - .and('contain.text', SECURITY_PROTOCOL_FIELD_LABEL); - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.hostname' }) - .should('be.visible') - .and('contain.text', HOSTNAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.hostname' }) - .scrollIntoView() - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.port' }) - .should('be.visible') - .and('contain.text', API_PORT_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.port', - inputType: 'number', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.userid', - }) - .should('be.visible') - .and('contain.text', USERNAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }) - .should('be.visible') - .and('be.enabled'); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', PASSWORD_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.password', - }) - .should('be.visible') - .and('contain.text', PASSWORD_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password-password-placeholder', - inputType: 'password', - }) - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - } - cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); - cy.getFormFooterButtonByTypeWithText({ - buttonText: isEdit ? 'Save' : 'Add', - buttonType: 'submit', - }) - .should('be.visible') - .and('be.disabled'); - if (isEdit) { - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.visible') - .and('be.disabled'); - } - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) - .should('be.visible') - .and('be.enabled'); -} - -function fillAzureStackForm({ nameValue, hostValue }) { - cy.getFormSelectFieldById({ selectId: 'type' }).select( - PROVIDER_TYPE_AZURE_STACK - ); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); - cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( - ZONE_OPTION_DEFAULT - ); - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type(TENANT_ID_VALUE); - cy.getFormInputFieldByIdAndType({ inputId: 'subscription' }).type( - SUBSCRIPTION_ID_VALUE - ); - cy.getFormSelectFieldById({ selectId: 'api_version' }).select( - API_VERSION_TYPE_2017 - ); - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }).select(SECURITY_PROTOCOL_SSL); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.hostname', - }).type(hostValue); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.port', - inputType: 'number', - }).type(PORT_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }).type(USERNAME_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password', - inputType: 'password', - }).type(PASSWORD_VALUE); -} - -function addAzureStackProviderAndOpenEditForm({ nameValue, hostValue }) { - fillAzureStackForm({ - nameValue, - hostValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.interceptApi({ - alias: 'addAzureStackProviderApi', - urlPattern: '/api/providers', - triggerFn: () => - cy - .getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }) - .click(), - responseInterceptor: (req) => { - // Let the request go through to the server and then override the response statusCode - // to 200, server will return internal_server_error(500) since we are using mock values - // for fields like host, port, etc. - req.continue((res) => { - res.send(200); - }); - }, - }); - selectCreatedProvider(nameValue); - // TODO: Switch to cy.interceptApi once its enhanced to support multiple api intercepts from a single event - cy.intercept( - 'GET', - /\/api\/providers\/(\d+)\?attributes=endpoints,authentications/, - (req) => { - const providerId = req.url.match(/\/api\/providers\/(\d+)\?/)[1]; - // Let the request go through to the server and then override the response statusCode to 200 and override the - // response body with the form input values, as these will be used to populate edit form in the UI. The "type" - // field value from the response will be used to hit to OPTIONS - /api/providers?type API - - // (like /api/providers?type=ManageIQ::Providers::AzureStack::CloudManager). - // If not overridden, server will return internal_server_error(500) since we are using mock values for - // fields like host, port, etc. - req.continue((res) => { - res.send(200, { - id: providerId, - type: 'ManageIQ::Providers::AzureStack::CloudManager', - name: nameValue, - zone_id: '2', - uid_ems: TENANT_ID_VALUE, - subscription: SUBSCRIPTION_ID_VALUE, - api_version: API_VERSION_TYPE_2017, - endpoints: [ - { - role: 'default', // role is required to populate host & port - hostname: hostValue, - port: PORT_VALUE, - security_protocol: 'ssl-with-validation', - }, - ], - authentications: [ - { - authtype: 'default', // authtype is required to populate host & port - userid: USERNAME_VALUE, - }, - ], - }); - }); - } - ).as('getProviderFieldValuesApi'); - // TODO: Switch to cy.interceptApi once its enhanced to support multiple api intercepts from a single event - cy.intercept( - 'GET', - '/api/zones?expand=resources&attributes=id,name,visible&filter[]=visible!=false&sort_by=name', // allow to hit server - (req) => { - req.continue((res) => { - res.send(200, { - name: 'zones', - count: 2, - subcount: 1, - subquery_count: 1, - pages: 1, - resources: [ - { - href: 'http://localhost:3000/api/zones/2', - id: '2', - name: ZONE_OPTION_DEFAULT, - visible: true, - }, - ], - }); - }); - } - ).as('getZoneDropdownOptionsApi'); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); - cy.wait('@getProviderFieldValuesApi'); - cy.wait('@getZoneDropdownOptionsApi'); -} - -// Methods for Azure -function validateAzureFormFields(isEdit) { - cy.getFormLabelByForAttribute({ forValue: 'type' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - if (isEdit) { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.disabled') - .find('option:selected') - .should('have.text', PROVIDER_TYPE_AZURE); - } else { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.enabled') - .select(PROVIDER_TYPE_AZURE); - } - cy.getFormLabelByForAttribute({ forValue: 'name' }) - .should('be.visible') - .and('contain.text', NAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) - .should('be.visible') - .and('contain.text', ZONE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'zone_id' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'provider_region' }) - .should('be.visible') - .and('contain.text', REGION_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'provider_region' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'uid_ems' }) - .should('be.visible') - .and('contain.text', TENANT_ID_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'subscription' }) - .should('be.visible') - .and('contain.text', SUBSCRIPTION_ID_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'subscription' }) - .should('be.visible') - .and('be.enabled'); - cy.contains('h3', 'Endpoint').should('be.visible'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.url' }) - .should('be.visible') - .and('contain.text', ENDPOINT_URL_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.url' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.userid', - }) - .should('be.visible') - .and('contain.text', CLIENT_ID_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }) - .scrollIntoView() - .should('be.visible') - .and('be.enabled'); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', CLIENT_KEY_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.password', - }) - .should('be.visible') - .and('contain.text', CLIENT_KEY_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password-password-placeholder', - inputType: 'password', - }) - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - } - cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); - cy.getFormFooterButtonByTypeWithText({ - buttonText: isEdit ? 'Save' : 'Add', - buttonType: 'submit', - }) - .should('be.visible') - .and('be.disabled'); - if (isEdit) { - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.visible') - .and('be.disabled'); - } - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) - .should('be.visible') - .and('be.enabled'); -} - -function fillAzureForm({ nameValue }) { - cy.getFormSelectFieldById({ selectId: 'type' }).select(PROVIDER_TYPE_AZURE); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); - cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( - ZONE_OPTION_DEFAULT - ); - cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( - REGION_OPTION_CENTRAL_INDIA - ); - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type(TENANT_ID_VALUE); - cy.getFormInputFieldByIdAndType({ inputId: 'subscription' }).type( - SUBSCRIPTION_ID_VALUE - ); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.url', - }).type(ENDPOINT_URL_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }).type(CLIENT_ID_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password', - inputType: 'password', - }).type(CLIENT_KEY_VALUE); -} - -function addAzureProviderAndOpenEditForm({ nameValue }) { - fillAzureForm({ - nameValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - selectCreatedProvider(nameValue); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); -} - -// Methods for Amazon EC2 -function validateAmazonEC2FormFields(isEdit) { - cy.getFormLabelByForAttribute({ forValue: 'type' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - if (isEdit) { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.disabled') - .find('option:selected') - .should('have.text', PROVIDER_TYPE_AMAZON_EC2); - } else { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.enabled') - .select(PROVIDER_TYPE_AMAZON_EC2); - } - cy.getFormLabelByForAttribute({ forValue: 'name' }) - .should('be.visible') - .and('contain.text', NAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) - .should('be.visible') - .and('contain.text', ZONE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'zone_id' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'provider_region' }) - .should('be.visible') - .and('contain.text', REGION_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'provider_region' }) - .should('be.visible') - .and('be.enabled'); - cy.contains('h3', 'Endpoints').should('be.visible'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.url' }) - .should('be.visible') - .and('contain.text', ENDPOINT_URL_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.url' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.service_account', - }) - .should('be.visible') - .and('contain.text', ASSUME_ROLE_ARN_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.service_account', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.userid', - }) - .should('be.visible') - .and('contain.text', ACCESS_KEY_ID_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }) - .should('be.visible') - .and('be.enabled'); - if (isEdit) { - cy.contains( - '.bx--fieldset legend.bx--label', - SECRET_ACCESS_KEY_FIELD_LABEL - ); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.password', - }) - .scrollIntoView() - .should('be.visible') - .and('contain.text', SECRET_ACCESS_KEY_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password-password-placeholder', - inputType: 'password', - }) - .scrollIntoView() - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - } - cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); - cy.tabs({ tabLabel: SMARTSTATE_DOCKER_TAB_LABEL }); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.smartstate_docker.userid', - }) - .should('be.visible') - .and('contain.text', USERNAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.smartstate_docker.userid', - }) - .should('be.visible') - .and('be.enabled'); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', PASSWORD_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.smartstate_docker.password', - }) - .should('be.visible') - .and('contain.text', PASSWORD_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: - 'authentications.smartstate_docker.password-password-placeholder', - inputType: 'password', - }) - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.smartstate_docker.password', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - } - cy.getFormFooterButtonByTypeWithText({ - buttonText: isEdit ? 'Save' : 'Add', - buttonType: 'submit', - }) - .should('be.visible') - .and('be.disabled'); - if (isEdit) { - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.visible') - .and('be.disabled'); - } - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) - .should('be.visible') - .and('be.enabled'); -} - -function fillAmazonEC2Form({ nameValue }) { - cy.getFormSelectFieldById({ selectId: 'type' }).select( - PROVIDER_TYPE_AMAZON_EC2 - ); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); - cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( - ZONE_OPTION_DEFAULT - ); - cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( - REGION_OPTION_CANADA - ); - cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.url' }).type( - ENDPOINT_URL_VALUE - ); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.service_account', - }).type(ASSUME_ROLE_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }).type(ACCESS_KEY_ID_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password', - inputType: 'password', - }).type(SECRET_ACCESS_KEY_VALUE); -} - -function addAmazonEC2ProviderAndOpenEditForm({ nameValue }) { - fillAmazonEC2Form({ - nameValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - selectCreatedProvider(nameValue); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); -} - -// Methods for IBM PowerVC -function validateIbmPowerVcFormFields(isEdit) { - cy.getFormLabelByForAttribute({ forValue: 'type' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - if (isEdit) { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.disabled') - .find('option:selected') - .should('have.text', PROVIDER_TYPE_IBM_POWERVC); - } else { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.enabled') - .select(PROVIDER_TYPE_IBM_POWERVC); - } - cy.getFormLabelByForAttribute({ forValue: 'name' }) - .should('be.visible') - .and('contain.text', NAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) - .should('be.visible') - .and('contain.text', ZONE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'zone_id' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'provider_region' }) - .should('be.visible') - .and('contain.text', PROVIDER_REGION_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'provider_region' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'tenant_mapping_enabled' }) - .should('be.visible') - .and('contain.text', TENANT_MAPPING_ENABLED_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'tenant_mapping_enabled', - inputType: 'checkbox', - }) - .should('be.visible') - .and('be.enabled'); - cy.contains('h3', 'Endpoints').should('be.visible'); - cy.getFormLabelByForAttribute({ - forValue: 'endpoints.default.security_protocol', - }) - .should('be.visible') - .and('contain.text', SECURITY_PROTOCOL_FIELD_LABEL); - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.hostname' }) - .scrollIntoView() - .should('be.visible') - .and('contain.text', POWERVC_API_ENDPOINT_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.hostname' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.port' }) - .should('be.visible') - .and('contain.text', API_PORT_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.port', - inputType: 'number', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.userid', - }) - .should('be.visible') - .and('contain.text', API_USERNAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }) - .should('be.visible') - .and('be.enabled'); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', API_PASSWORD_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.password', - }) - .should('be.visible') - .and('contain.text', API_PASSWORD_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password-password-placeholder', - inputType: 'password', - }) - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - } - cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); - cy.tabs({ tabLabel: EVENTS_TAB_LABEL }); - cy.getFormLabelByForAttribute({ forValue: 'event_stream_selection' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'event_stream_selection' }) - .should('be.visible') - .and('be.enabled'); - cy.tabs({ tabLabel: RSA_KEY_PAIR_TAB_LABEL }); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.ssh_keypair.userid', - }) - .should('be.visible') - .and('contain.text', USERNAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.ssh_keypair.userid', - }) - .should('be.visible') - .and('be.enabled'); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', PRIVATE_KEY_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.ssh_keypair.auth_key', - }) - .should('be.visible') - .and('contain.text', PRIVATE_KEY_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.ssh_keypair.auth_key-password-placeholder', - inputType: 'password', - }) - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormTextareaById({ - textareaId: 'authentications.ssh_keypair.auth_key', - }) - .should('be.visible') - .and('be.enabled'); - } - cy.tabs({ tabLabel: IMAGE_EXPORT_TAB_LABEL }); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.node.userid', - }) - .should('be.visible') - .and('contain.text', POWERVC_COMMON_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.node.userid', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.node.options', - }) - .should('be.visible') - .and('contain.text', ANSIBLE_ACCESS_METHOD_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'authentications.node.options' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.node.auth_key_password', - }) - .should('be.visible') - .and('contain.text', POWERVC_COMMON_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.node.auth_key_password', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.node.auth_key', - }) - .should('be.visible') - .and('contain.text', POWERVC_COMMON_FIELD_LABEL); - cy.getFormTextareaById({ - textareaId: 'authentications.node.auth_key', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormFooterButtonByTypeWithText({ - buttonText: isEdit ? 'Save' : 'Add', - buttonType: 'submit', - }) - .scrollIntoView() - .should('be.visible') - .and('be.disabled'); - if (isEdit) { - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.visible') - .and('be.disabled'); - } - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) - .should('be.visible') - .and('be.enabled'); -} - -function fillIbmPowerVcForm({ nameValue, hostValue }) { - cy.getFormSelectFieldById({ selectId: 'type' }).select( - PROVIDER_TYPE_IBM_POWERVC - ); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); - cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( - ZONE_OPTION_DEFAULT - ); - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }) - .clear() - .type(DOMAIN_ID_DEFAULT_VALUE); - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }).select(SECURITY_PROTOCOL_SSL); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.hostname', - }).type(hostValue); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.port', - inputType: 'number', - }) - .clear() - .type(PORT_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }).type(USERNAME_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password', - inputType: 'password', - }).type(PASSWORD_VALUE); -} - -function addIbmPowerVcProviderAndOpenEditForm({ nameValue, hostValue }) { - fillIbmPowerVcForm({ - nameValue, - hostValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - selectCreatedProvider(nameValue); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); -} - -// Methods for IBM Cloud Infrastructure Center -function validateIbmCloudInfrastructureCenterFormFields(isEdit) { - cy.getFormLabelByForAttribute({ forValue: 'type' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - if (isEdit) { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.disabled') - .find('option:selected') - .should('have.text', PROVIDER_TYPE_IBM_CIC); - } else { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.enabled') - .select(PROVIDER_TYPE_IBM_CIC); - } - cy.getFormLabelByForAttribute({ forValue: 'name' }) - .should('be.visible') - .and('contain.text', NAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) - .should('be.visible') - .and('contain.text', ZONE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'zone_id' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'provider_region' }) - .should('be.visible') - .and('contain.text', PROVIDER_REGION_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'provider_region' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'api_version' }) - .should('be.visible') - .and('contain.text', API_VERSION_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'api_version' }) - .should('be.visible') - .and('be.enabled') - .select(API_VERSION_TYPE_V3); - cy.getFormLabelByForAttribute({ forValue: 'uid_ems' }) - .should('be.visible') - .and('contain.text', DOMAIN_ID_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'tenant_mapping_enabled' }) - .should('be.visible') - .and('contain.text', TENANT_MAPPING_ENABLED_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'tenant_mapping_enabled', - inputType: 'checkbox', - }) - .should('be.visible') - .and('be.enabled'); - cy.contains('h3', 'Endpoints').should('be.visible'); - cy.contains('h3', 'Default').should('be.visible'); - cy.getFormLabelByForAttribute({ - forValue: 'endpoints.default.security_protocol', - }) - .should('be.visible') - .and('contain.text', SECURITY_PROTOCOL_FIELD_LABEL); - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'endpoints.default.hostname', - }).should('be.visible'); - cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.hostname' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.port' }) - .should('be.visible') - .and('contain.text', API_PORT_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.port', - inputType: 'number', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.userid', - }).should('be.visible'); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }) - .should('be.visible') - .and('be.enabled'); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', PASSWORD_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.password', - }) - .should('be.visible') - .and('contain.text', PASSWORD_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password-password-placeholder', - inputType: 'password', - }) - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - } - cy.contains('h3', 'Events').scrollIntoView().should('be.visible'); - cy.getFormLabelByForAttribute({ forValue: 'event_stream_selection' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'event_stream_selection' }) - .should('be.visible') - .and('be.enabled') - .select(EVENT_STREAM_TYPE_STF); - cy.getFormLabelByForAttribute({ - forValue: 'endpoints.stf.security_protocol', - }) - .should('be.visible') - .and('contain.text', SECURITY_PROTOCOL_FIELD_LABEL); - cy.getFormSelectFieldById({ - selectId: 'endpoints.stf.security_protocol', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'endpoints.stf.hostname', - }).should('be.visible'); - cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.stf.hostname' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.stf.port' }) - .should('be.visible') - .and('contain.text', API_PORT_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.stf.port', - inputType: 'number', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormSelectFieldById({ selectId: 'event_stream_selection' }).select( - EVENT_STREAM_TYPE_AMQP - ); - cy.getFormLabelByForAttribute({ - forValue: 'endpoints.amqp.hostname', - }).should('be.visible'); - cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.amqp.hostname' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.amqp.port' }) - .should('be.visible') - .and('contain.text', API_PORT_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.amqp.port', - inputType: 'number', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.amqp.userid', - }) - .should('be.visible') - .and('contain.text', USERNAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.amqp.userid', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.amqp.password', - }) - .should('be.visible') - .and('contain.text', PASSWORD_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.amqp.password', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.ssh_keypair.userid', - }) - .should('be.visible') - .and('contain.text', USERNAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.ssh_keypair.userid', - }) - .should('be.visible') - .and('be.enabled'); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', PRIVATE_KEY_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.ssh_keypair.auth_key', - }) - .should('be.visible') - .and('contain.text', PRIVATE_KEY_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.ssh_keypair.auth_key-password-placeholder', - inputType: 'password', - }) - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormTextareaById({ - textareaId: 'authentications.ssh_keypair.auth_key', - }) - .should('be.visible') - .and('be.enabled'); - } - cy.getFormFooterButtonByTypeWithText({ - buttonText: isEdit ? 'Save' : 'Add', - buttonType: 'submit', - }) - .scrollIntoView() - .should('be.visible') - .and('be.disabled'); - if (isEdit) { - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.visible') - .and('be.enabled'); - } - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) - .should('be.visible') - .and('be.enabled'); -} - -function fillIbmCloudInfrastructureCenterForm({ nameValue, hostValue }) { - cy.getFormSelectFieldById({ selectId: 'type' }).select(PROVIDER_TYPE_IBM_CIC); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); - cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( - ZONE_OPTION_DEFAULT - ); - cy.getFormInputFieldByIdAndType({ inputId: 'provider_region' }).type( - PROVIDER_REGION_VALUE - ); - cy.getFormSelectFieldById({ selectId: 'api_version' }).select( - API_VERSION_TYPE_V3 - ); - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type( - DOMAIN_ID_DEFAULT_VALUE - ); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.hostname', - }).type(hostValue); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.port', - inputType: 'number', - }) - .clear() - .type(PORT_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }).type(USERNAME_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password', - inputType: 'password', - }).type(PASSWORD_VALUE); -} - -function addIbmCloudInfrastructureCenterProviderAndOpenEditForm({ - nameValue, - hostValue, -}) { - fillIbmCloudInfrastructureCenterForm({ - nameValue, - hostValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - selectCreatedProvider(nameValue); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); -} - -// Methods for OpenStack -function validateOpenstackFormFields(isEdit) { - cy.getFormLabelByForAttribute({ forValue: 'type' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - if (isEdit) { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.disabled') - .find('option:selected') - .should('have.text', PROVIDER_TYPE_OPENSTACK); - } else { - cy.getFormSelectFieldById({ selectId: 'type' }) - .should('be.visible') - .and('be.enabled') - .select(PROVIDER_TYPE_OPENSTACK); - } - cy.getFormLabelByForAttribute({ forValue: 'name' }) - .should('be.visible') - .and('contain.text', NAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'zone_id' }) - .should('be.visible') - .and('contain.text', ZONE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'zone_id' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'provider_region' }) - .should('be.visible') - .and('contain.text', PROVIDER_REGION_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'provider_region' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'provider_id' }) - .should('be.visible') - .and('contain.text', OPENSTACK_INFRA_PROVIDER_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'provider_id' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'api_version' }) - .should('be.visible') - .and('contain.text', API_VERSION_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'api_version' }) - .should('be.visible') - .and('be.enabled') - .select(API_VERSION_TYPE_V3); - cy.getFormLabelByForAttribute({ forValue: 'uid_ems' }) - .should('be.visible') - .and('contain.text', DOMAIN_ID_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'tenant_mapping_enabled' }) - .should('be.visible') - .and('contain.text', TENANT_MAPPING_ENABLED_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'tenant_mapping_enabled', - inputType: 'checkbox', - }) - .should('be.visible') - .and('be.enabled'); - cy.contains('h3', 'Endpoints').should('be.visible'); - cy.contains('h3', 'Default').should('be.visible'); - cy.getFormLabelByForAttribute({ - forValue: 'endpoints.default.security_protocol', - }) - .should('be.visible') - .and('contain.text', SECURITY_PROTOCOL_FIELD_LABEL); - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'endpoints.default.hostname', - }).should('be.visible'); - cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.default.hostname' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.default.port' }) - .should('be.visible') - .and('contain.text', API_PORT_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.port', - inputType: 'number', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.userid', - }).should('be.visible'); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }) - .should('be.visible') - .and('be.enabled'); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', PASSWORD_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.default.password', - }) - .should('be.visible') - .and('contain.text', PASSWORD_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password-password-placeholder', - inputType: 'password', - }) - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - } - cy.contains('h3', 'Events').scrollIntoView().should('be.visible'); - cy.getFormLabelByForAttribute({ forValue: 'event_stream_selection' }) - .should('be.visible') - .and('contain.text', TYPE_FIELD_LABEL); - cy.getFormSelectFieldById({ selectId: 'event_stream_selection' }) - .should('be.visible') - .and('be.enabled') - .select(EVENT_STREAM_TYPE_STF); - cy.getFormLabelByForAttribute({ - forValue: 'endpoints.stf.security_protocol', - }) - .should('be.visible') - .and('contain.text', SECURITY_PROTOCOL_FIELD_LABEL); - cy.getFormSelectFieldById({ - selectId: 'endpoints.stf.security_protocol', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'endpoints.stf.hostname', - }).should('be.visible'); - cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.stf.hostname' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.stf.port' }) - .should('be.visible') - .and('contain.text', API_PORT_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.stf.port', - inputType: 'number', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormSelectFieldById({ selectId: 'event_stream_selection' }).select( - EVENT_STREAM_TYPE_AMQP - ); - cy.getFormLabelByForAttribute({ - forValue: 'endpoints.amqp.hostname', - }).should('be.visible'); - cy.getFormInputFieldByIdAndType({ inputId: 'endpoints.amqp.hostname' }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ forValue: 'endpoints.amqp.port' }) - .should('be.visible') - .and('contain.text', API_PORT_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.amqp.port', - inputType: 'number', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.amqp.userid', - }) - .should('be.visible') - .and('contain.text', USERNAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.amqp.userid', - }) - .should('be.visible') - .and('be.enabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.amqp.password', - }) - .should('be.visible') - .and('contain.text', PASSWORD_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.amqp.password', - inputType: 'password', - }) - .should('be.visible') - .and('be.enabled'); - cy.contains('button', 'Validate').should('be.visible').and('be.disabled'); - cy.getFormLabelByForAttribute({ - forValue: 'authentications.ssh_keypair.userid', - }) - .should('be.visible') - .and('contain.text', USERNAME_FIELD_LABEL); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.ssh_keypair.userid', - }) - .should('be.visible') - .and('be.enabled'); - if (isEdit) { - cy.contains('.bx--fieldset legend.bx--label', PRIVATE_KEY_FIELD_LABEL); - } else { - cy.getFormLabelByForAttribute({ - forValue: 'authentications.ssh_keypair.auth_key', - }) - .should('be.visible') - .and('contain.text', PRIVATE_KEY_FIELD_LABEL); - } - if (isEdit) { - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.ssh_keypair.auth_key-password-placeholder', - inputType: 'password', - }) - .should('be.visible') - .and('be.disabled'); - } else { - cy.getFormTextareaById({ - textareaId: 'authentications.ssh_keypair.auth_key', - }) - .should('be.visible') - .and('be.enabled'); - } - cy.getFormFooterButtonByTypeWithText({ - buttonText: isEdit ? 'Save' : 'Add', - buttonType: 'submit', - }) - .scrollIntoView() - .should('be.visible') - .and('be.disabled'); - if (isEdit) { - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.visible') - .and('be.enabled'); - } - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }) - .should('be.visible') - .and('be.enabled'); -} - -function fillOpenstackForm({ nameValue, hostValue }) { - cy.getFormSelectFieldById({ selectId: 'type' }).select( - PROVIDER_TYPE_OPENSTACK - ); - cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type(nameValue); - cy.getFormSelectFieldById({ selectId: 'zone_id' }).select( - ZONE_OPTION_DEFAULT - ); - cy.getFormInputFieldByIdAndType({ inputId: 'provider_region' }).type( - PROVIDER_REGION_VALUE - ); - cy.getFormSelectFieldById({ selectId: 'api_version' }).select( - API_VERSION_TYPE_V3 - ); - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type( - DOMAIN_ID_DEFAULT_VALUE - ); - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }).select(SECURITY_PROTOCOL_SSL); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.hostname', - }).type(hostValue); - cy.getFormInputFieldByIdAndType({ - inputId: 'endpoints.default.port', - inputType: 'number', - }) - .clear() - .type(PORT_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.userid', - }).type(USERNAME_VALUE); - cy.getFormInputFieldByIdAndType({ - inputId: 'authentications.default.password', - inputType: 'password', - }).type(PASSWORD_VALUE); -} - -function addOpenstackProviderAndOpenEditForm({ nameValue, hostValue }) { - fillOpenstackForm({ - nameValue, - hostValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - selectCreatedProvider(nameValue); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_PROVIDER_CONFIG_OPTION); -} - -// Other common methods -function selectCreatedProvider(providerName) { - // Set pagination to 200 items per page to include the target provider despite pending deletions - // The test will create up to 55 records in total - cy.get( - '.miq-fieldset-content .miq-pagination select#bx-pagination-select-1' - ).select('200'); - cy.get('.miq-data-table table tbody tr').each((row) => { - if ( - row.find('td').filter((_ind, el) => el.innerText.trim() === providerName) - .length - ) { - if (!row.hasClass('bx--data-table--selected')) { - cy.wrap(row) - .find('.bx--checkbox--inline label.bx--checkbox-label') - .click(); - } - // Exit loop - return false; - } - // Returning null to get rid of eslint warning, has no impact - return null; - }); -} - -function assertValidationFailureMessage() { - cy.contains( - '.ddorg__carbon-error-helper-text', - VALIDATION_FAILED_COMMON_ERROR - ); -} - -function assertValidationSuccessMessage() { - cy.contains('.bx--form__helper-text', VALIDATION_SUCCESSFUL_COMMON_MESSAGE); -} - -function assertNameAlreadyExistsError() { - cy.contains('#name-error-msg', NAME_ALRADY_EXISTS_ERROR); -} - -function validate({ stubErrorResponse, errorMessage }) { - let response = { state: 'Finished', status: 'Error' }; - if (stubErrorResponse) { - response = { - ...response, - message: errorMessage, - }; - } else { - response = { ...response, status: 'Ok', task_results: {} }; - } - // not using cy.interceptApi because each validate call requires a fresh alias registration - // reusing the same intercept callback results in it returning the first response object - cy.intercept('GET', '/api/tasks/*?attributes=task_results', response).as( - 'validateApi' - ); - cy.contains('button', 'Validate').click(); - cy.wait('@validateApi'); -} - -function selectProviderAndDeleteWithOptionalFlashMessageCheck({ - createdProviderName, - assertDeleteFlashMessage, -}) { - selectCreatedProvider(createdProviderName); - cy.interceptApi({ - alias: 'deleteProviderApi', - urlPattern: '/ems_cloud/button?pressed=ems_cloud_delete', - triggerFn: () => - cy.expect_browser_confirm_with_text({ - confirmTriggerFn: () => - cy.toolbar(CONFIG_TOOLBAR_BUTTON, REMOVE_PROVIDER_CONFIG_OPTION), - containsText: REMOVE_PROVIDER_BROWSER_ALERT_MESSAGE, - }), - onApiResponse: () => { - if (assertDeleteFlashMessage) { - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_DELETE_OPERATION); - } - }, - }); -} - -function cleanUp({ createdProviderName }) { - cy.url() - .then((url) => { - // Navigate to cloud providers table view - if (!url.endsWith(CLOUD_PROVIDERS_LIST_URL)) { - cy.visit(CLOUD_PROVIDERS_LIST_URL); - } - }) - .then(() => { - selectProviderAndDeleteWithOptionalFlashMessageCheck({ - createdProviderName, - assertDeleteFlashMessage: false, - }); - }); -} +import { generateProviderTests } from '../../../../../support/commands/provider_helper_commands'; +import { getProviderConfig, PROVIDER_TYPES } from './provider-factory'; describe('Automate Cloud Provider form operations: Compute > Clouds > Providers > Configuration > Add a New Cloud Provider', () => { beforeEach(() => { cy.login(); - cy.menu( - COMPUTE_MENU_OPTION, - CLOUDS_AUTOMATION_MENU_OPTION, - PROVIDERS_MENU_OPTION - ); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - }); - - describe('Validate cloud provider type: VMware vCloud', () => { - describe('Validate add form', () => { - it('Validate visibility of elements', () => { - validateVmwareVcloudFormFields(false); - }); - - it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { - fillVmwareVcloudForm({ - nameValue: `${VMWARE_VCLOUD_NAME_VALUE} - Verify add form validation error`, - hostValue: 'vmware-vcloud.verify-add-form-validation-error.com', - }); - validate({ - stubErrorResponse: true, - errorMessage: VMWARE_VCLOUD_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + add/refresh/delete operations', () => { - const nameFieldValue = `${VMWARE_VCLOUD_NAME_VALUE} - Verify validate/add/refresh/delete operations`; - fillVmwareVcloudForm({ - nameValue: nameFieldValue, - hostValue: - 'vmware-vcloud.verify-validate-add-refresh-delete-operations.com', - }); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - selectCreatedProvider(nameFieldValue); - cy.expect_browser_confirm_with_text({ - confirmTriggerFn: () => - cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), - containsText: REFRESH_OPERATION_MESSAGE, - }); - cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); - - // FIXME: remove this block once bug is fixed - // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back - /* ==================================================================== */ - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - /* ==================================================================== */ - - selectProviderAndDeleteWithOptionalFlashMessageCheck({ - createdProviderName: nameFieldValue, - assertDeleteFlashMessage: true, - }); - }); - }); - - describe('Validate edit form', () => { - /** - * The provider name is set in this variable at the start of each test, - * allowing afterEach to identify it for deletion. - */ - let nameFieldValue; - - it('Validate visibility of elements', () => { - nameFieldValue = `${VMWARE_VCLOUD_NAME_VALUE} - Verify edit form elements`; - addVmwareVcloudProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'vmware-vcloud.verify-edit-form-elements.com', - }); - - validateVmwareVcloudFormFields(true); - }); - - it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { - nameFieldValue = `${VMWARE_VCLOUD_NAME_VALUE} - Verify edit form validation error`; - addVmwareVcloudProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'vmware-vcloud.verify-edit-form-validation-error.com', - }); - - cy.getFormSelectFieldById({ selectId: 'api_version' }).select( - API_VERSION_TYPE_V9 - ); - validate({ - stubErrorResponse: true, - errorMessage: VMWARE_VCLOUD_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.enabled') - .click(); - cy.getFormSelectFieldById({ selectId: 'api_version' }) - .find('option:selected') - .should('have.text', API_VERSION_TYPE_V5); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Cancel', - }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + edit operation', () => { - nameFieldValue = `${VMWARE_VCLOUD_NAME_VALUE} - Verify validate/edit operations`; - addVmwareVcloudProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'vmware-vcloud.verify-validate-edit-operations.com', - }); - - cy.getFormSelectFieldById({ selectId: 'api_version' }).select( - API_VERSION_TYPE_V9 - ); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Save', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - - describe('Provider name uniqueness validation', () => { - const nameFieldValue = `${VMWARE_VCLOUD_NAME_VALUE} - Verify duplicate restriction`; - - beforeEach(() => { - fillVmwareVcloudForm({ - nameValue: nameFieldValue, - hostValue: 'vmware-vcloud.verify-duplicate-restriction.com', - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - }); - - it('Should display error on duplicate name usage', () => { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - fillVmwareVcloudForm({ - nameValue: nameFieldValue, - hostValue: 'vmware-vcloud.verify-duplicate-restriction.com', - }); - assertNameAlreadyExistsError(); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - }); - - describe('Validate cloud provider type: Oracle Cloud', () => { - describe('Validate add form', () => { - it('Validate visibility of elements', () => { - validateOracleCloudFormFields(false); - }); - - it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { - fillOracleCloudForm({ - nameValue: `${ORACLE_CLOUD_NAME_VALUE} - Verify add form validation error`, - }); - validate({ - stubErrorResponse: true, - errorMessage: ORACLE_CLOUD_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + add/refresh/delete operations', () => { - const nameValue = `${ORACLE_CLOUD_NAME_VALUE} - Verify validate/add/refresh/delete operations`; - fillOracleCloudForm({ - nameValue, - }); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - selectCreatedProvider(nameValue); - cy.expect_browser_confirm_with_text({ - confirmTriggerFn: () => - cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), - containsText: REFRESH_OPERATION_MESSAGE, - }); - cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); - - // FIXME: remove this block once bug is fixed - // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back - /* ==================================================================== */ - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - /* ==================================================================== */ - - selectProviderAndDeleteWithOptionalFlashMessageCheck({ - createdProviderName: nameValue, - assertDeleteFlashMessage: true, - }); - }); - }); - - describe('Validate edit form', () => { - /** - * The provider name is set in this variable at the start of each test, - * allowing afterEach to identify it for deletion. - */ - let nameFieldValue; - - it('Validate visibility of elements', () => { - nameFieldValue = `${ORACLE_CLOUD_NAME_VALUE} - Verify edit form elements`; - addOracleCloudProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - validateOracleCloudFormFields(true); - }); - - it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { - nameFieldValue = `${ORACLE_CLOUD_NAME_VALUE} - Verify edit form validation error`; - addOracleCloudProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( - REGION_OPTION_MELBOURNE - ); - validate({ - stubErrorResponse: true, - errorMessage: ORACLE_CLOUD_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.enabled') - .click(); - cy.getFormSelectFieldById({ selectId: 'provider_region' }) - .find('option:selected') - .should('have.text', REGION_OPTION_HYDERABAD); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Cancel', - }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + edit operation', () => { - nameFieldValue = `${ORACLE_CLOUD_NAME_VALUE} - Verify validate/edit operations`; - addOracleCloudProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( - REGION_OPTION_MELBOURNE - ); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Save', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - - describe('Provider name uniqueness validation', () => { - const nameFieldValue = `${ORACLE_CLOUD_NAME_VALUE} - Verify duplicate restriction`; - - beforeEach(() => { - fillOracleCloudForm({ - nameValue: nameFieldValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - }); - - it('Should display error on duplicate name usage', () => { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - fillOracleCloudForm({ - nameValue: nameFieldValue, - }); - assertNameAlreadyExistsError(); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - }); - - describe('Validate cloud provider type: IBM Cloud VPC', () => { - describe('Validate add form', () => { - it('Validate visibility of elements', () => { - validateIbmCloudVpcFormFields(false); - }); - - it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { - fillIbmCloudVpcForm({ - nameValue: `${IBM_CLOUD_VPC_NAME_VALUE} - Verify add form validation error`, - }); - validate({ - stubErrorResponse: true, - errorMessage: IBM_CLOUD_VPC_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + add/refresh/delete operations', () => { - const nameValue = `${IBM_CLOUD_VPC_NAME_VALUE} - Verify validate/add/refresh/delete operations`; - fillIbmCloudVpcForm({ - nameValue, - }); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - selectCreatedProvider(nameValue); - cy.expect_browser_confirm_with_text({ - confirmTriggerFn: () => - cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), - containsText: REFRESH_OPERATION_MESSAGE, - }); - cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); - - // FIXME: remove this block once bug is fixed - // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back - /* ==================================================================== */ - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - /* ==================================================================== */ - - selectProviderAndDeleteWithOptionalFlashMessageCheck({ - createdProviderName: nameValue, - assertDeleteFlashMessage: true, - }); - }); - }); - - describe('Validate edit form', () => { - /** - * The provider name is set in this variable at the start of each test, - * allowing afterEach to identify it for deletion. - */ - let nameFieldValue; - - it('Validate visibility of elements', () => { - nameFieldValue = `${IBM_CLOUD_VPC_NAME_VALUE} - Verify edit form elements`; - addIbmCloudVpcProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - validateIbmCloudVpcFormFields(true); - }); - - it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { - nameFieldValue = `${IBM_CLOUD_VPC_NAME_VALUE} - Verify edit form validation error`; - addIbmCloudVpcProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( - REGION_OPTION_SPAIN - ); - validate({ - stubErrorResponse: true, - errorMessage: IBM_CLOUD_VPC_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.enabled') - .click(); - cy.getFormSelectFieldById({ selectId: 'provider_region' }) - .find('option:selected') - .should('have.text', REGION_OPTION_AUSTRALIA); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Cancel', - }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + edit operation', () => { - nameFieldValue = `${IBM_CLOUD_VPC_NAME_VALUE} - Verify validate/edit operations`; - addIbmCloudVpcProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( - REGION_OPTION_SPAIN - ); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Save', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - - describe('Provider name uniqueness validation', () => { - const nameFieldValue = `${IBM_CLOUD_VPC_NAME_VALUE} - Verify duplicate restriction`; - - beforeEach(() => { - fillIbmCloudVpcForm({ - nameValue: nameFieldValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - }); - - it('Should display error on duplicate name usage', () => { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - fillIbmCloudVpcForm({ - nameValue: nameFieldValue, - }); - assertNameAlreadyExistsError(); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - }); - - describe('Validate cloud provider type: IBM Power Systems Virtual Servers', () => { - describe('Validate add form', () => { - it('Validate visibility of elements', () => { - validateIbmPowerSystemsVirtualServersFormFields(false); - }); - - it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { - fillIbmPowerSystemsVirtualServersForm({ - nameValue: `${IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_NAME_VALUE} - Verify add form validation error`, - }); - validate({ - stubErrorResponse: true, - errorMessage: IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + add/refresh/delete operations', () => { - const nameValue = `${IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_NAME_VALUE} - Verify validate/add/refresh/delete operations`; - fillIbmPowerSystemsVirtualServersForm({ - nameValue, - }); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - selectCreatedProvider(nameValue); - cy.expect_browser_confirm_with_text({ - confirmTriggerFn: () => - cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), - containsText: REFRESH_OPERATION_MESSAGE, - }); - cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); - - // FIXME: remove this block once bug is fixed - // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back - /* ==================================================================== */ - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - /* ==================================================================== */ - - selectProviderAndDeleteWithOptionalFlashMessageCheck({ - createdProviderName: nameValue, - assertDeleteFlashMessage: true, - }); - }); - }); - - describe('Validate edit form', () => { - /** - * The provider name is set in this variable at the start of each test, - * allowing afterEach to identify it for deletion. - */ - let nameFieldValue; - - it('Validate visibility of elements', () => { - nameFieldValue = `${IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_NAME_VALUE} - Verify edit form elements`; - addIbmPowerSystemsVirtualServersProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - validateIbmPowerSystemsVirtualServersFormFields(true); - }); - - it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { - nameFieldValue = `${IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_NAME_VALUE} - Verify edit form validation error`; - addIbmPowerSystemsVirtualServersProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type('-xr4q'); - validate({ - stubErrorResponse: true, - errorMessage: IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.enabled') - .click(); - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).should( - 'have.value', - GUID_VALUE - ); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Cancel', - }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + edit operation', () => { - nameFieldValue = `${IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_NAME_VALUE} - Verify validate/edit operations`; - addIbmPowerSystemsVirtualServersProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - cy.getFormInputFieldByIdAndType({ inputId: 'uid_ems' }).type('-xr4q'); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Save', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ - createdProviderName: nameFieldValue, - }); - }); - }); - - describe('Provider name uniqueness validation', () => { - const nameFieldValue = `${IBM_POWER_SYSTEMS_VIRTUAL_SERVERS_NAME_VALUE} - Verify duplicate restriction`; - - beforeEach(() => { - fillIbmPowerSystemsVirtualServersForm({ - nameValue: nameFieldValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - }); - - it('Should display error on duplicate name usage', () => { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - fillIbmPowerSystemsVirtualServersForm({ - nameValue: nameFieldValue, - }); - assertNameAlreadyExistsError(); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ - createdProviderName: nameFieldValue, - }); - }); - }); - }); - - describe('Validate cloud provider type: Google Compute Engine', () => { - describe('Validate add form', () => { - it('Validate visibility of elements', () => { - validateGoogleComputeEngineFormFields(false); - }); - - it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { - fillGoogleComputeEngineForm({ - nameValue: `${GOOGLE_COMPUTE_ENGINE_NAME_VALUE} - Verify add form validation error`, - }); - validate({ - stubErrorResponse: true, - errorMessage: GOOGLE_COMPUTE_ENGINE_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + add/refresh/delete operations', () => { - const nameFieldValue = `${GOOGLE_COMPUTE_ENGINE_NAME_VALUE} - Verify validate/add/refresh/delete operations`; - fillGoogleComputeEngineForm({ - nameValue: nameFieldValue, - }); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - selectCreatedProvider(nameFieldValue); - cy.expect_browser_confirm_with_text({ - confirmTriggerFn: () => - cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), - containsText: REFRESH_OPERATION_MESSAGE, - }); - cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); - - // FIXME: remove this block once bug is fixed - // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back - /* ==================================================================== */ - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - /* ==================================================================== */ - - selectProviderAndDeleteWithOptionalFlashMessageCheck({ - createdProviderName: nameFieldValue, - assertDeleteFlashMessage: true, - }); - }); - }); - - describe('Validate edit form', () => { - /** - * The provider name is set in this variable at the start of each test, - * allowing afterEach to identify it for deletion. - */ - let nameFieldValue; - - it('Validate visibility of elements', () => { - nameFieldValue = `${GOOGLE_COMPUTE_ENGINE_NAME_VALUE} - Verify edit form elements`; - addGoogleComputeEngineProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - validateGoogleComputeEngineFormFields(true); - }); - - it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { - nameFieldValue = `${GOOGLE_COMPUTE_ENGINE_NAME_VALUE} - Verify edit form validation error`; - addGoogleComputeEngineProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - cy.getFormInputFieldByIdAndType({ inputId: 'project' }).type('-76g1'); - validate({ - stubErrorResponse: true, - errorMessage: GOOGLE_COMPUTE_ENGINE_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.enabled') - .click(); - cy.getFormInputFieldByIdAndType({ inputId: 'project' }).should( - 'have.value', - PROJECT_ID_VALUE - ); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Cancel', - }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + edit operation', () => { - nameFieldValue = `${GOOGLE_COMPUTE_ENGINE_NAME_VALUE} - Verify validate/edit operations`; - addGoogleComputeEngineProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - cy.getFormInputFieldByIdAndType({ inputId: 'project' }).type('-76g1'); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Save', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - - describe('Provider name uniqueness validation', () => { - const nameFieldValue = `${GOOGLE_COMPUTE_ENGINE_NAME_VALUE} - Verify duplicate restriction`; - - beforeEach(() => { - fillGoogleComputeEngineForm({ - nameValue: nameFieldValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - }); - - it('Should display error on duplicate name usage', () => { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - fillGoogleComputeEngineForm({ - nameValue: nameFieldValue, - }); - assertNameAlreadyExistsError(); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); + cy.menu('Compute', 'Clouds', 'Providers'); + cy.toolbar('Configuration', 'Add a New Cloud Provider'); }); - describe('Validate cloud provider type: Azure Stack', () => { - describe('Validate add form', () => { - it('Validate visibility of elements', () => { - validateAzureStackFormFields(false); - }); - - it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { - fillAzureStackForm({ - nameValue: `${AZURE_STACK_NAME_VALUE} - Verify add form validation error`, - hostValue: 'azure-stack.verify-add-form-validation-error.com', - }); - validate({ - stubErrorResponse: true, - errorMessage: AZURE_STACK_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + add/refresh/delete operations', () => { - const nameFieldValue = `${AZURE_STACK_NAME_VALUE} - Verify validate/add/refresh/delete operations`; - fillAzureStackForm({ - nameValue: nameFieldValue, - hostValue: - 'azure-stack.verify-validate-add-refresh-delete-operations.com', - }); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.interceptApi({ - alias: 'addAzureStackProviderApi', - urlPattern: '/api/providers', - triggerFn: () => - cy - .getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }) - .should('be.enabled') - .click(), - responseInterceptor: (req) => { - // Let the request go through to the server(so that the data is created) and then override - // the response statusCode to 200, server will return internal_server_error(500) since we are - // using mock values for fields like host, port, etc. - req.continue((res) => { - res.send(200); - }); - }, - }); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - selectCreatedProvider(nameFieldValue); - cy.expect_browser_confirm_with_text({ - confirmTriggerFn: () => - cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), - containsText: REFRESH_OPERATION_MESSAGE, - }); - cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); - - // FIXME: Remove this block once bug is fixed - // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back - /* ==================================================================== */ - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - /* ==================================================================== */ - - selectProviderAndDeleteWithOptionalFlashMessageCheck({ - createdProviderName: nameFieldValue, - assertDeleteFlashMessage: true, - }); - }); - }); - - describe('Validate edit form', () => { - /** - * The provider name is set in this variable at the start of each test, - * allowing afterEach to identify it for deletion. - */ - let nameFieldValue; - - it('Validate visibility of elements', () => { - nameFieldValue = `${AZURE_STACK_NAME_VALUE} - Verify edit form elements`; - addAzureStackProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'azure-stack.verify-edit-form-elements.com', - }); - - validateAzureStackFormFields(true); - }); - - it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { - nameFieldValue = `${AZURE_STACK_NAME_VALUE} - Verify edit form validation error`; - addAzureStackProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'azure-stack.verify-edit-form-validation-error.com', - }); - - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }).select(SECURITY_PROTOCOL_NON_SSL); - validate({ - stubErrorResponse: true, - errorMessage: AZURE_STACK_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.enabled') - .click(); - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }) - .find('option:selected') - .should('have.text', SECURITY_PROTOCOL_SSL); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Cancel', - }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + edit operation', () => { - nameFieldValue = `${AZURE_STACK_NAME_VALUE} - Verify validate/edit operations`; - addAzureStackProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'azure-stack.verify-validate-edit-operations.com', - }); - - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }).select(SECURITY_PROTOCOL_NON_SSL); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.interceptApi({ - method: 'PATCH', - alias: 'editAzureStackProviderApi', - urlPattern: /\/api\/providers\/\d+/, - triggerFn: () => - cy - .getFormFooterButtonByTypeWithText({ - buttonText: 'Save', - buttonType: 'submit', - }) - .should('be.enabled') - .click(), - responseInterceptor: (req) => { - // Let the request go through to the server(so that the data is updated) and then override - // the response statusCode to 200, server will return internal_server_error(500) since we are - // using mock values for fields like host, port, etc. - req.continue((res) => { - res.send(200); - }); - }, - }); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - - describe('Provider name uniqueness validation', () => { - const nameFieldValue = `${AZURE_STACK_NAME_VALUE} - Verify duplicate restriction`; - - beforeEach(() => { - fillAzureStackForm({ - nameValue: nameFieldValue, - hostValue: 'azure-stack.verify-duplicate-restriction.com', - }); - validate({ - stubErrorResponse: false, - }); - cy.interceptApi({ - alias: 'addAzureStackProviderApi', - urlPattern: '/api/providers', - triggerFn: () => - cy - .getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }) - .click(), - responseInterceptor: (req) => { - // Let the request go through to the server(so that the data is created) and then override - // the response statusCode to 200, server will return internal_server_error(500) since we are - // using mock values for fields like host, port, etc. - req.continue((res) => { - res.send(200); - }); - }, - }); - }); - - it('Should display error on duplicate name usage', () => { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - fillAzureStackForm({ - nameValue: nameFieldValue, - hostValue: 'azure-stack.verify-duplicate-restriction.com', - }); - assertNameAlreadyExistsError(); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - }); - - describe('Validate cloud provider type: Azure', () => { - describe('Validate add form', () => { - it('Validate visibility of elements', () => { - validateAzureFormFields(false); - }); - - it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { - fillAzureForm({ - nameValue: `${AZURE_NAME_VALUE} - Verify add form validation error`, - }); - validate({ - stubErrorResponse: true, - errorMessage: AZURE_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + add/refresh/delete operations', () => { - const nameFieldValue = `${AZURE_NAME_VALUE} - Verify validate/add/refresh/delete operations`; - fillAzureForm({ - nameValue: nameFieldValue, - }); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - selectCreatedProvider(nameFieldValue); - cy.expect_browser_confirm_with_text({ - confirmTriggerFn: () => - cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), - containsText: REFRESH_OPERATION_MESSAGE, - }); - cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); - - // TODO: remove this block once bug is fixed - // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back - /* ==================================================================== */ - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - /* ==================================================================== */ - - selectProviderAndDeleteWithOptionalFlashMessageCheck({ - createdProviderName: nameFieldValue, - assertDeleteFlashMessage: true, - }); - }); - }); - - describe('Validate edit form', () => { - /** - * The provider name is set in this variable at the start of each test, - * allowing afterEach to identify it for deletion. - */ - let nameFieldValue; - - it('Validate visibility of elements', () => { - nameFieldValue = `${AZURE_NAME_VALUE} - Verify edit form elements`; - addAzureProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - validateAzureFormFields(true); - }); + // Generate tests for VMware vCloud provider + const vmwareVcloudConfig = getProviderConfig(PROVIDER_TYPES.VMWARE_VCLOUD); + generateProviderTests(vmwareVcloudConfig); - it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { - nameFieldValue = `${AZURE_NAME_VALUE} - Verify edit form validation error`; - addAzureProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); + // Generate tests for Amazon EC2 provider + const amazonEC2Config = getProviderConfig(PROVIDER_TYPES.AMAZON_EC2); + generateProviderTests(amazonEC2Config); - cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( - REGION_OPTION_CENTRAL_US - ); - validate({ - stubErrorResponse: true, - errorMessage: AZURE_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.enabled') - .click(); - cy.getFormSelectFieldById({ selectId: 'provider_region' }) - .find('option:selected') - .should('have.text', REGION_OPTION_CENTRAL_INDIA); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); + // Generate tests for Azure provider + const azureConfig = getProviderConfig(PROVIDER_TYPES.AZURE); + generateProviderTests(azureConfig); - it('Verify successful validate + edit operation', () => { - nameFieldValue = `${AZURE_NAME_VALUE} - Verify validate/edit operations`; - addAzureProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); + // Generate tests for Azure Stack provider (requires special handling) + const azureStackConfig = getProviderConfig(PROVIDER_TYPES.AZURE_STACK); + generateProviderTests(azureStackConfig); - cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( - REGION_OPTION_CENTRAL_US - ); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Save', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - }); + // Generate tests for Google Compute Engine provider + const googleComputeConfig = getProviderConfig(PROVIDER_TYPES.GOOGLE_COMPUTE); + generateProviderTests(googleComputeConfig); - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); + // Generate tests for IBM Cloud VPC provider + const ibmCloudVpcConfig = getProviderConfig(PROVIDER_TYPES.IBM_CLOUD_VPC); + generateProviderTests(ibmCloudVpcConfig); - describe('Provider name uniqueness validation', () => { - const nameFieldValue = `${AZURE_NAME_VALUE} - Verify duplicate restriction`; - - beforeEach(() => { - fillAzureForm({ - nameValue: nameFieldValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - }); - - it('Should display error on duplicate name usage', () => { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - fillAzureForm({ - nameValue: nameFieldValue, - }); - assertNameAlreadyExistsError(); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - }); - - describe('Validate cloud provider type: Amazon EC2', () => { - describe('Validate add form', () => { - it('Validate visibility of elements', () => { - validateAmazonEC2FormFields(false); - }); - - it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { - fillAmazonEC2Form({ - nameValue: `${AMAZON_EC2_NAME_VALUE} - Verify add form validation error`, - }); - validate({ - stubErrorResponse: true, - errorMessage: AMAZON_EC2_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + add/refresh/delete operations', () => { - const nameFieldValue = `${AMAZON_EC2_NAME_VALUE} - Verify validate/add/refresh/delete operations`; - fillAmazonEC2Form({ - nameValue: nameFieldValue, - }); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - selectCreatedProvider(nameFieldValue); - cy.expect_browser_confirm_with_text({ - confirmTriggerFn: () => - cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), - containsText: REFRESH_OPERATION_MESSAGE, - }); - cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); - - // TODO: remove this block once bug is fixed - // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back - /* ==================================================================== */ - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - /* ==================================================================== */ - - selectProviderAndDeleteWithOptionalFlashMessageCheck({ - createdProviderName: nameFieldValue, - assertDeleteFlashMessage: true, - }); - }); - }); - - describe('Validate edit form', () => { - /** - * The provider name is set in this variable at the start of each test, - * allowing afterEach to identify it for deletion. - */ - let nameFieldValue; - - it('Validate visibility of elements', () => { - nameFieldValue = `${AMAZON_EC2_NAME_VALUE} - Verify edit form elements`; - addAmazonEC2ProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - validateAmazonEC2FormFields(true); - }); - - it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { - nameFieldValue = `${AMAZON_EC2_NAME_VALUE} - Verify edit form validation error`; - addAmazonEC2ProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( - REGION_OPTION_ASIA_PACIFIC - ); - validate({ - stubErrorResponse: true, - errorMessage: AMAZON_EC2_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.enabled') - .click(); - cy.getFormSelectFieldById({ selectId: 'provider_region' }) - .find('option:selected') - .should('have.text', REGION_OPTION_CANADA); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + edit operation', () => { - nameFieldValue = `${AMAZON_EC2_NAME_VALUE} - Verify validate/edit operations`; - addAmazonEC2ProviderAndOpenEditForm({ - nameValue: nameFieldValue, - }); - - cy.getFormSelectFieldById({ selectId: 'provider_region' }).select( - REGION_OPTION_ASIA_PACIFIC - ); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Save', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - - describe('Provider name uniqueness validation', () => { - const nameFieldValue = `${AMAZON_EC2_NAME_VALUE} - Verify duplicate restriction`; - - beforeEach(() => { - fillAmazonEC2Form({ - nameValue: nameFieldValue, - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - }); - - it('Should display error on duplicate name usage', () => { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - fillAmazonEC2Form({ - nameValue: nameFieldValue, - }); - assertNameAlreadyExistsError(); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - }); - - describe('Validate cloud provider type: IBM PowerVC', () => { - describe('Validate add form', () => { - it('Validate visibility of elements', () => { - validateIbmPowerVcFormFields(false); - }); - - it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { - fillIbmPowerVcForm({ - nameValue: `${IBM_POWERVC_NAME_VALUE} - Verify add form validation error`, - hostValue: 'ibm-powervc.verify-add-form-validation-error.com', - }); - validate({ - stubErrorResponse: true, - errorMessage: IBM_POWERVC_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + add/refresh/delete operations', () => { - const nameFieldValue = `${IBM_POWERVC_NAME_VALUE} - Verify validate/add/refresh/delete operations`; - fillIbmPowerVcForm({ - nameValue: nameFieldValue, - hostValue: - 'ibm-powervc.verify-validate-add-refresh-delete-operations.com', - }); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - selectCreatedProvider(nameFieldValue); - cy.expect_browser_confirm_with_text({ - confirmTriggerFn: () => - cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), - containsText: REFRESH_OPERATION_MESSAGE, - }); - cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); - - // TODO: remove this block once bug is fixed - // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back - /* ==================================================================== */ - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - /* ==================================================================== */ - - selectProviderAndDeleteWithOptionalFlashMessageCheck({ - createdProviderName: nameFieldValue, - assertDeleteFlashMessage: true, - }); - }); - }); - - describe('Validate edit form', () => { - /** - * The provider name is set in this variable at the start of each test, - * allowing afterEach to identify it for deletion. - */ - let nameFieldValue; - - it('Validate visibility of elements', () => { - nameFieldValue = `${IBM_POWERVC_NAME_VALUE} - Verify edit form elements`; - addIbmPowerVcProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'ibm-powervc.verify-edit-form-elements.com', - }); - - validateIbmPowerVcFormFields(true); - }); - - it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { - nameFieldValue = `${IBM_POWERVC_NAME_VALUE} - Verify edit form validation error`; - addIbmPowerVcProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'ibm-powervc.verify-edit-form-validation-error.com', - }); - - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }).select(SECURITY_PROTOCOL_NON_SSL); - validate({ - stubErrorResponse: true, - errorMessage: IBM_POWERVC_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.enabled') - .click(); - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }) - .find('option:selected') - .should('have.text', SECURITY_PROTOCOL_SSL); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + edit operation', () => { - nameFieldValue = `${IBM_POWERVC_NAME_VALUE} - Verify validate/edit operations`; - addIbmPowerVcProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'ibm-powervc.verify-validate-edit-operations.com', - }); - - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }).select(SECURITY_PROTOCOL_NON_SSL); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Save', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - - describe('Provider name uniqueness validation', () => { - const nameFieldValue = `${IBM_POWERVC_NAME_VALUE} - Verify duplicate restriction`; - - beforeEach(() => { - fillIbmPowerVcForm({ - nameValue: nameFieldValue, - hostValue: 'ibm-powervc.verify-duplicate-restriction.com', - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - }); - - it('Should display error on duplicate name usage', () => { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - fillIbmPowerVcForm({ - nameValue: nameFieldValue, - hostValue: 'ibm-powervc.verify-duplicate-restriction.com', - }); - assertNameAlreadyExistsError(); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - }); - - describe('Validate cloud provider type: IBM Cloud Infrastructure Center', () => { - describe('Validate add form', () => { - it('Validate visibility of elements', () => { - validateIbmCloudInfrastructureCenterFormFields(false); - }); - - it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { - fillIbmCloudInfrastructureCenterForm({ - nameValue: `${IBM_CIC_NAME_VALUE} - Verify add form validation error`, - hostValue: 'ibm-cic.verify-add-form-validation-error.com', - }); - validate({ - stubErrorResponse: true, - errorMessage: IBM_CIC_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + add/refresh/delete operations', () => { - const nameFieldValue = `${IBM_CIC_NAME_VALUE} - Verify validate/add/refresh/delete operations`; - fillIbmCloudInfrastructureCenterForm({ - nameValue: nameFieldValue, - hostValue: - 'ibm-cic.verify-validate-add-refresh-delete-operations.com', - }); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - selectCreatedProvider(nameFieldValue); - cy.expect_browser_confirm_with_text({ - confirmTriggerFn: () => - cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), - containsText: REFRESH_OPERATION_MESSAGE, - }); - cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); - - // TODO: remove this block once bug is fixed - // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back - /* ==================================================================== */ - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - /* ==================================================================== */ - - selectProviderAndDeleteWithOptionalFlashMessageCheck({ - createdProviderName: nameFieldValue, - assertDeleteFlashMessage: true, - }); - }); - }); - - describe('Validate edit form', () => { - /** - * The provider name is set in this variable at the start of each test, - * allowing afterEach to identify it for deletion. - */ - let nameFieldValue; - - it('Validate visibility of elements', () => { - nameFieldValue = `${IBM_CIC_NAME_VALUE} - Verify edit form elements`; - addIbmCloudInfrastructureCenterProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'ibm-cic.verify-edit-form-elements.com', - }); - - validateIbmCloudInfrastructureCenterFormFields(true); - }); - - it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { - nameFieldValue = `${IBM_CIC_NAME_VALUE} - Verify edit form validation error`; - addIbmCloudInfrastructureCenterProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'ibm-cic.verify-edit-form-validation-error.com', - }); - - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }).select(SECURITY_PROTOCOL_NON_SSL); - validate({ - stubErrorResponse: true, - errorMessage: IBM_CIC_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.enabled') - .click(); - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }) - .find('option:selected') - .should('have.text', SECURITY_PROTOCOL_SSL); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + edit operation', () => { - nameFieldValue = `${IBM_CIC_NAME_VALUE} - Verify validate/edit operations`; - addIbmCloudInfrastructureCenterProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'ibm-cic.verify-validate-edit-operations.com', - }); - - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }).select(SECURITY_PROTOCOL_NON_SSL); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Save', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - - describe('Provider name uniqueness validation', () => { - const nameFieldValue = `${IBM_CIC_NAME_VALUE} - Verify duplicate restriction`; - - beforeEach(() => { - fillIbmCloudInfrastructureCenterForm({ - nameValue: nameFieldValue, - hostValue: 'ibm-cic.verify-duplicate-restriction.com', - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - }); - - it('Should display error on duplicate name usage', () => { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - fillIbmCloudInfrastructureCenterForm({ - nameValue: nameFieldValue, - hostValue: 'ibm-cic.verify-duplicate-restriction.com', - }); - assertNameAlreadyExistsError(); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - }); - - describe('Validate cloud provider type: Openstack', () => { - describe('Validate add form', () => { - it('Validate visibility of elements', () => { - validateOpenstackFormFields(false); - }); - - it('Should show the error message from the task_results API upon validation failure and validate cancel button behavior', () => { - fillOpenstackForm({ - nameValue: `${OPENSTACK_NAME_VALUE} - Verify add form validation error`, - hostValue: 'openstack.verify-add-form-validation-error.com', - }); - validate({ - stubErrorResponse: true, - errorMessage: OPENSTACK_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + add/refresh/delete operations', () => { - const nameFieldValue = `${OPENSTACK_NAME_VALUE} - Verify validate/add/refresh/delete operations`; - fillOpenstackForm({ - nameValue: nameFieldValue, - hostValue: - 'openstack.verify-validate-add-refresh-delete-operations.com', - }); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - selectCreatedProvider(nameFieldValue); - cy.expect_browser_confirm_with_text({ - confirmTriggerFn: () => - cy.toolbar(CONFIG_TOOLBAR_BUTTON, REFRESH_CONFIG_OPTION), - containsText: REFRESH_OPERATION_MESSAGE, - }); - cy.expect_flash(flashClassMap.success, REFRESH_OPERATION_MESSAGE); - - // TODO: remove this block once bug is fixed - // Bug: After refresh, config option other than add remains disabled and requires any action to be performed to enable it back - /* ==================================================================== */ - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - /* ==================================================================== */ - - selectProviderAndDeleteWithOptionalFlashMessageCheck({ - createdProviderName: nameFieldValue, - assertDeleteFlashMessage: true, - }); - }); - }); - - describe('Validate edit form', () => { - /** - * The provider name is set in this variable at the start of each test, - * allowing afterEach to identify it for deletion. - */ - let nameFieldValue; - - it('Validate visibility of elements', () => { - nameFieldValue = `${OPENSTACK_NAME_VALUE} - Verify edit form elements`; - addOpenstackProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'openstack.verify-edit-form-elements.com', - }); - - validateOpenstackFormFields(true); - }); - - it("Should show the error message from the task_results API upon validation failure and validate reset & cancel buttons' behavior", () => { - nameFieldValue = `${OPENSTACK_NAME_VALUE} - Verify edit form validation error`; - addOpenstackProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'openstack.verify-edit-form-validation-error.com', - }); - - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }).select(SECURITY_PROTOCOL_NON_SSL); - validate({ - stubErrorResponse: true, - errorMessage: OPENSTACK_VALIDATION_ERROR, - }); - assertValidationFailureMessage(); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Reset' }) - .should('be.enabled') - .click(); - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }) - .find('option:selected') - .should('have.text', SECURITY_PROTOCOL_SSL); - cy.getFormFooterButtonByTypeWithText({ buttonText: 'Cancel' }).click(); - cy.expect_flash( - flashClassMap.success, - FLASH_MESSAGE_OPERATION_CANCELLED - ); - }); - - it('Verify successful validate + edit operation', () => { - nameFieldValue = `${OPENSTACK_NAME_VALUE} - Verify validate/edit operations`; - addOpenstackProviderAndOpenEditForm({ - nameValue: nameFieldValue, - hostValue: 'openstack.verify-validate-edit-operations.com', - }); - - cy.getFormSelectFieldById({ - selectId: 'endpoints.default.security_protocol', - }).select(SECURITY_PROTOCOL_NON_SSL); - validate({ - stubErrorResponse: false, - }); - assertValidationSuccessMessage(); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Save', - buttonType: 'submit', - }) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_SAVED); - }); - - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); + // Generate tests for IBM Power Systems Virtual Servers provider + const ibmPowerSystemsConfig = getProviderConfig( + PROVIDER_TYPES.IBM_POWER_SYSTEMS + ); + generateProviderTests(ibmPowerSystemsConfig); - describe('Provider name uniqueness validation', () => { - const nameFieldValue = `${OPENSTACK_NAME_VALUE} - Verify duplicate restriction`; + // Generate tests for IBM PowerVC provider + const ibmPowerVcConfig = getProviderConfig(PROVIDER_TYPES.IBM_POWERVC); + generateProviderTests(ibmPowerVcConfig); - beforeEach(() => { - fillOpenstackForm({ - nameValue: nameFieldValue, - hostValue: 'openstack.verify-duplicate-restriction.com', - }); - validate({ - stubErrorResponse: false, - }); - cy.getFormFooterButtonByTypeWithText({ - buttonText: 'Add', - buttonType: 'submit', - }).click(); - }); + // Generate tests for IBM Cloud Infrastructure Center provider + const ibmCicConfig = getProviderConfig(PROVIDER_TYPES.IBM_CIC); + generateProviderTests(ibmCicConfig); - it('Should display error on duplicate name usage', () => { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROVIDER_CONFIG_OPTION); - fillOpenstackForm({ - nameValue: nameFieldValue, - hostValue: 'openstack.verify-duplicate-restriction.com', - }); - assertNameAlreadyExistsError(); - }); + // Generate tests for Oracle Cloud provider + const oracleCloudConfig = getProviderConfig(PROVIDER_TYPES.ORACLE_CLOUD); + generateProviderTests(oracleCloudConfig); - afterEach(() => { - // TODO: add better clean up approach - cleanUp({ createdProviderName: nameFieldValue }); - }); - }); - }); + // Generate tests for OpenStack provider + const openstackConfig = getProviderConfig(PROVIDER_TYPES.OPENSTACK); + generateProviderTests(openstackConfig); }); From 6d3b4b094eeae95a52140a92019992351af85538 Mon Sep 17 00:00:00 2001 From: asirvadAbrahamVarghese Date: Tue, 7 Oct 2025 17:15:36 +0530 Subject: [PATCH 4/4] Added provider_helper_commands section in readme --- cypress/README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/cypress/README.md b/cypress/README.md index 9a62c53280d..c5bc8c91c00 100644 --- a/cypress/README.md +++ b/cypress/README.md @@ -95,6 +95,27 @@ ManageIQ implements the following cypress extensions: * `cy.validateFormFields(fieldConfigs)` - validates form input fields based on provided configurations. `fieldConfigs` is an array of field configuration objects with properties: `id` (required) - the ID of the form field, `fieldType` (optional, default: 'input') - the type of field ('input', 'select', 'textarea'), `inputFieldType` (optional, default: 'text') - the type of input field ('text', 'password', 'number'), `shouldBeDisabled` (optional, default: false) - whether the field should be disabled, `expectedValue` (optional) - the expected value of the field. e.g. `cy.validateFormFields([{ id: 'name', shouldBeDisabled: true }, { id: 'role', fieldType: 'select', expectedValue: 'admin' }]);` or using constants: `cy.validateFormFields([{ [FIELD_CONFIG_KEYS.ID]: 'email', [FIELD_CONFIG_KEYS.INPUT_FIELD_TYPE]: 'email' }, { [FIELD_CONFIG_KEYS.ID]: 'name', [FIELD_CONFIG_KEYS.SHOULD_BE_DISABLED]: true }]);` * `cy.validateFormFooterButtons(buttonConfigs)` - validates form buttons based on provided configurations. `buttonConfigs` is an array of button configuration objects with properties: `buttonText` (required) - the text of the button, `buttonType` (optional, default: 'button') - the type of button (e.g., 'submit', 'reset'), `shouldBeDisabled` (optional, default: false) - whether the button should be disabled. e.g. `cy.validateFormFooterButtons([{ buttonText: 'Cancel' }, { buttonText: 'Submit', buttonType: 'submit', shouldBeDisabled: true }]);` or using constants: `cy.validateFormFooterButtons([{ [BUTTON_CONFIG_KEYS.TEXT]: 'Cancel' }]);` +##### provider_helper_commands + +* `cy.fillCommonFormFields(providerConfig, nameValue)` - fills common form fields that are present in all provider forms. `providerConfig` is the provider configuration object. `nameValue` is the name to use for the provider. +* `cy.fillFormFields(fields, values)` - fills form fields based on field definitions and values. `fields` is an array of field definition objects. `values` is an object containing field values. +* `cy.fillProviderForm(providerConfig, nameValue, hostValue)` - fills a provider form based on provider configuration. `providerConfig` is the provider configuration object. `nameValue` is the name to use for the provider. `hostValue` is the hostname to use for the provider. +* `cy.validateCommonFormFields(providerType, isEdit)` - validates common form fields that are present in all provider forms. `providerType` is the type of provider to be validated. `isEdit` is whether the form is in edit mode. +* `cy.validateFormFields(fields, isEdit)` - validates form fields based on field definitions. `fields` is an array of field definition objects. `isEdit` is whether the form is in edit mode. +* `cy.validateFormButtons(providerType, isEdit)` - validates form buttons (validate, add/save, reset, cancel). `providerType` is the type of provider to be validated. `isEdit` is whether the form is in edit mode. +* `cy.validateProviderForm(providerConfig, isEdit)` - validates a provider form based on provider configuration. `providerConfig` is the provider configuration object. `isEdit` is whether the form is in edit mode. +* `cy.updateProviderFieldsForEdit(providerConfig)` - updates provider fields for edit validation tests based on provider type. `providerConfig` is the provider configuration object. +* `cy.selectCreatedProvider(providerName)` - selects a created provider from the data table. `providerName` is the name of the provider to select. +* `cy.addProviderAndOpenEditForm(providerConfig, nameValue, hostValue, isAzureStack)` - adds a provider and opens the edit form. `providerConfig` is the provider configuration object. `nameValue` is the name to use for the provider. `hostValue` is the hostname to use for the provider. `isAzureStack` is an optional boolean parameter that indicates whether the provider is Azure Stack, which requires special handling when opening the edit form. +* `cy.interceptAddProviderApi()` - This command intercepts the POST request to '/api/providers' that occurs when adding a provider. For Azure Stack providers, it allows the request to reach the server (so data is created) and forces a successful response. +* `cy.assertValidationFailureMessage()` - asserts validation failure message. +* `cy.assertValidationSuccessMessage()` - asserts validation success message. +* `cy.assertNameAlreadyExistsError()` - asserts name already exists error. +* `cy.validate({ stubErrorResponse, errorMessage })` - performs validation with optional error response stubbing. `stubErrorResponse` is whether to stub an error response. `errorMessage` is the error message to show. +* `cy.selectProviderAndDeleteWithOptionalFlashMessage({ createdProviderName, assertDeleteFlashMessage })` - deletes a provider with optional flash message check. `createdProviderName` is the name of the provider to delete. `assertDeleteFlashMessage` is whether to assert the delete flash message. +* `cy.cleanUp({ createdProviderName })` - cleans up a provider by deleting it. `createdProviderName` is the name of the provider to clean up. +* `generateProviderTests(providerConfig)` - generates all test suites for a provider. `providerConfig` is the provider configuration object. + #### Assertions * `cy.expect_explorer_title(title)` - check that the title on an explorer screen matches the provided title. `title`: String for the title.