diff --git a/cypress/e2e/ui/Settings/Application-Settings/schedule.cy.js b/cypress/e2e/ui/Settings/Application-Settings/schedule.cy.js index ae7a932e724..161d2110853 100644 --- a/cypress/e2e/ui/Settings/Application-Settings/schedule.cy.js +++ b/cypress/e2e/ui/Settings/Application-Settings/schedule.cy.js @@ -1,171 +1,137 @@ /* eslint-disable no-undef */ import { flashClassMap } from '../../../../support/assertions/assertion_constants'; -const textConstants = { - // List items - schedulesAccordionItem: 'Schedules', - - // Field values - initialScheduleName: 'Test-name', - editedScheduleName: 'Dummy-name', - initialDescription: 'Test description', - editedDescription: 'Dummy description', - actionTypeVmAnalysis: 'vm', - actionTypeTemplateAnalysis: 'miq_template', - actionTypeHostAnalysis: 'host', - actionTypeContainerAnalysis: 'container_image', - actionTypeClusterAnalysis: 'emscluster', - actionTypeDataStoreAnalysis: 'storage', - actionTypeVmCompilanceCheck: 'vm_check_compliance', - actionTypeHostCompilanceCheck: 'host_check_compliance', - actionTypeContainerCompilanceCheck: 'container_image_check_compliance', - actionTypeAutomationTasks: 'automation_request', - filterTypeVmCluster: 'cluster', - timerTypeOnce: 'Once', - timerTypeHourly: 'Hourly', - timerTypeDaily: 'Daily', - timerTypeWeekly: 'Weekly', - timerTypeMonthly: 'Monthly', - frequencyTypeHour: '1 Hour', - timezoneTypeHawaii: '(GMT-10:00) Hawaii', - initialStartDate: '06/30/2025', - editedStartDate: '07/21/2025', - startTime: '11:23', - - // Buttons - saveButton: 'Save', - cancelButton: 'Cancel', - resetButton: 'Reset', - - // Config options - configToolbarButton: 'Configuration', - addScheduleConfigOption: 'Add a new Schedule', - deleteScheduleConfigOption: 'Delete this Schedule from the Database', - editScheduleConfigOption: 'Edit this Schedule', - disableScheduleConfigOption: 'Disable this Schedule', - enableScheduleConfigOption: 'Enable this Schedule', - queueScheduleConfigOption: 'Queue up this Schedule to run now', - - // Menu options - settingsMenuOption: 'Settings', - appSettingsMenuOption: 'Application Settings', - - // Flash message text snippets - flashMessageScheduleQueued: 'queued to run', - flashMessageOperationCanceled: 'cancelled', - flashMessageScheduleDisabled: 'disabled', - flashMessageScheduleEnabled: 'enabled', - flashMessageScheduleSaved: 'saved', - flashMessageResetSchedule: 'reset', - flashMessageScheduleDeleted: 'delete successful', - flashMessageFailedToAddSchedule: 'failed', - - // Browser alert text snippets - browserAlertDeleteConfirmText: 'will be permanently removed', -}; - -const { - settingsMenuOption, - appSettingsMenuOption, - actionTypeVmAnalysis, - actionTypeTemplateAnalysis, - actionTypeHostAnalysis, - actionTypeContainerAnalysis, - actionTypeClusterAnalysis, - actionTypeDataStoreAnalysis, - actionTypeVmCompilanceCheck, - actionTypeHostCompilanceCheck, - actionTypeContainerCompilanceCheck, - actionTypeAutomationTasks, - timerTypeOnce, - timerTypeHourly, - timerTypeDaily, - timerTypeWeekly, - timerTypeMonthly, - cancelButton, - saveButton, - initialScheduleName, - editScheduleConfigOption, - editedScheduleName, - editedDescription, - editedStartDate, - resetButton, - initialDescription, - initialStartDate, - disableScheduleConfigOption, - enableScheduleConfigOption, - queueScheduleConfigOption, - addScheduleConfigOption, - frequencyTypeHour, - timezoneTypeHawaii, - startTime, - deleteScheduleConfigOption, - schedulesAccordionItem, - configToolbarButton, - flashMessageScheduleQueued, - flashMessageOperationCanceled, - flashMessageScheduleDisabled, - flashMessageScheduleEnabled, - flashMessageScheduleSaved, - flashMessageResetSchedule, - flashMessageScheduleDeleted, - flashMessageFailedToAddSchedule, - browserAlertDeleteConfirmText, -} = textConstants; - -function selectConfigMenu(menuOption = addScheduleConfigOption) { - return cy.toolbar(configToolbarButton, menuOption); +// Component route url +const COMPONENT_ROUTE_URL = '/ops/explorer'; + +// List items +const SCHEDULES_ACCORDION_ITEM = 'Schedules'; +const MANAGEIQ_REGION_ACCORDION_ITEM = /^ManageIQ Region:/; + +// Field values +const BASIC_INFO_SUB_HEADER = 'Basic Information'; +const NAME_FIELD_LABEL = 'Name'; +const DESCRIPTION_FIELD_LABEL = 'Description'; +const ACTIVE_CHECKBOX_FIELD_LABEL = 'Active'; +const ACTION_TYPE_FIELD_LABEL = 'Action'; +const FILTER_TYPE_FIELD_LABEL = 'Filter'; +const ZONE_FIELD_LABEL = 'Zone'; +const OBJECT_DETAILS_SUB_HEADER = 'Object Details'; +const SYSTEM_FIELD_LABEL = 'System/Process'; +const MESSAGE_FIELD_LABEL = 'Message'; +const REQUEST_FIELD_LABEL = 'Request'; +const OBJECT_LABEL_TEXT = 'Object'; +const OBJECT_TYPE_FIELD_LABEL = 'Type'; +const OBJECT_TYPE_CLOUD_NETWORK = 'Cloud Network'; +const ATTRIBUTE_PAIRS_SUB_HEADER = 'Attribute/Value Pairs'; +const TIMER_TYPE_FIELD_LABEL = 'Run'; +const TIMER_VALUE_FIELD_LABEL = 'Every'; +const TIME_ZONE_FIELD_LABEL = 'Time Zone'; +const START_DATE_FIELD_LABEL = 'Starting Date'; +const START_TIME_FIELD_LABEL = 'Starting Time'; +const INITIAL_SCHEDULE_NAME = 'Test-name'; +const EDITED_SCHEDULE_NAME = 'Dummy-name'; +const INITIAL_DESCRIPTION = 'Test description'; +const EDITED_DESCRIPTION = 'Dummy description'; +const ACTION_TYPE_VM_ANALYSIS = 'vm'; +const ACTION_TYPE_TEMPLATE_ANALYSIS = 'miq_template'; +const ACTION_TYPE_HOST_ANALYSIS = 'host'; +const ACTION_TYPE_CONTAINER_ANALYSIS = 'container_image'; +const ACTION_TYPE_CLUSTER_ANALYSIS = 'emscluster'; +const ACTION_TYPE_DATA_STORE_ANALYSIS = 'storage'; +const ACTION_TYPE_VM_COMPILANCE_CHECK = 'vm_check_compliance'; +const ACTION_TYPE_HOST_COMPILANCE_CHECK = 'host_check_compliance'; +const ACTION_TYPE_CONTAINER_COMPILANCE_CHECK = + 'container_image_check_compliance'; +const ACTION_TYPE_AUTOMATION_TASKS = 'automation_request'; +const TIMER_TYPE_ONCE = 'Once'; +const TIMER_TYPE_HOURLY = 'Hourly'; +const TIMER_TYPE_DAILY = 'Daily'; +const TIMER_TYPE_WEEKLY = 'Weekly'; +const TIMER_TYPE_MONTHLY = 'Monthly'; +const FREQUENCY_TYPE_HOUR = '1 Hour'; +const TIME_ZONE_TYPE_HAWAII = '(GMT-10:00) Hawaii'; +const INITIAL_START_DATE = '06/30/2025'; +const EDITED_START_DATE = '07/21/2025'; +const START_TIME = '11:23'; + +// Buttons +const SAVE_BUTTON_TEXT = 'Save'; +const CANCEL_BUTTON_TEXT = 'Cancel'; +const RESET_BUTTON_TEXT = 'Reset'; + +// Config options +const CONFIG_TOOLBAR_BUTTON = 'Configuration'; +const ADD_SCHEDULE_CONFIG_OPTION = 'Add a new Schedule'; +const DELETE_SCHEDULE_CONFIG_OPTION = 'Delete this Schedule from the Database'; +const EDIT_SCHEDULE_CONFIG_OPTION = 'Edit this Schedule'; +const DISABLE_SCHEDULE_CONFIG_OPTION = 'Disable this Schedule'; +const ENABLE_SCHEDULE_CONFIG_OPTION = 'Enable this Schedule'; +const QUEUE_SCHEDULE_CONFIG_OPTION = 'Queue up this Schedule to run now'; + +// Menu options +const SETTINGS_OPTION = 'Settings'; +const APP_SETTINGS_OPTION = 'Application Settings'; + +// Flash message text snippets +const FLASH_MESSAGE_SCHEDULE_QUEUED = 'queued'; +const FLASH_MESSAGE_OPERATION_CANCELED = 'cancel'; +const FLASH_MESSAGE_SCHEDULE_DISABLED = 'disabled'; +const FLASH_MESSAGE_SCHEDULE_ENABLED = 'enabled'; +const FLASH_MESSAGE_SCHEDULE_SAVED = 'saved'; +const FLASH_MESSAGE_RESET_SCHEDULE = 'reset'; +const FLASH_MESSAGE_SCHEDULE_DELETED = 'delete'; +const FLASH_MESSAGE_FAILED_TO_ADD_SCHEDULE = 'failed'; + +// Browser alert text snippets +const BROWSER_ALERT_DELETE_CONFIRM_TEXT = 'removed'; + +function selectConfigMenu(menuOption) { + return cy.toolbar(CONFIG_TOOLBAR_BUTTON, menuOption); } function addSchedule() { - selectConfigMenu(); + // Open add schedule form + selectConfigMenu(ADD_SCHEDULE_CONFIG_OPTION); // Checks if Save button is disabled initially - cy.contains( - '#main-content .bx--btn-set button[type="submit"]', - saveButton - ).should('be.disabled'); + cy.getFormFooterButtonByType(SAVE_BUTTON_TEXT, 'submit').should( + 'be.disabled' + ); // Adding data - cy.get('input#name').type(initialScheduleName); - cy.get('input#description').type(initialDescription); - cy.get('input[type="checkbox"]#enabled').check({ force: true }); + cy.getFormInputFieldById('name').type(INITIAL_SCHEDULE_NAME); + cy.getFormInputFieldById('description').type(INITIAL_DESCRIPTION); + // Check "Active" checkbox using its associated label + cy.getFormLabelByInputId('enabled').click(); // Select Action type option: 'VM Analysis' - cy.get('select#action_typ').select(actionTypeVmAnalysis); + cy.getFormSelectFieldById('action_typ').select(ACTION_TYPE_VM_ANALYSIS); // Select Filter type option: 'A Single VM' - cy.get('select#filter_typ').select(actionTypeVmAnalysis); + cy.getFormSelectFieldById('filter_typ').select(ACTION_TYPE_VM_ANALYSIS); // Select Run option: 'Hours' - cy.get('select#timer_typ').select(timerTypeHourly); + cy.getFormSelectFieldById('timer_typ').select(TIMER_TYPE_HOURLY); // Select Every option: '1 Hour' - cy.get('select#timer_value').select(frequencyTypeHour); + cy.getFormSelectFieldById('timer_value').select(FREQUENCY_TYPE_HOUR); // Select Time zone option: '(GMT-10:00) Hawaii' - cy.get('input[role="combobox"]#time_zone').click(); - cy.contains('[role="option"]', timezoneTypeHawaii) - .should('be.visible') - .click(); - cy.get('input#start_date').type(initialStartDate); - cy.get('input#start_time').type(startTime); + cy.getFormInputFieldById('time_zone').click(); + cy.contains('[role="option"]', TIME_ZONE_TYPE_HAWAII).click(); + cy.getFormInputFieldById('start_date').type(INITIAL_START_DATE); + cy.getFormInputFieldById('start_time').type(START_TIME); // Intercepting the API call for adding a new schedule - cy.intercept('POST', '/ops/schedule_edit/new?button=save').as( - 'addScheduleApi' - ); - cy.contains('#main-content .bx--btn-set button[type="submit"]', saveButton) - .should('be.enabled') // Checks if Save button is enabled once all required fields are filled - .click(); - // Wait for the API call to complete - cy.wait('@addScheduleApi'); -} - -function deleteSchedule(scheduleName = initialScheduleName) { - // Selecting the schedule and intercepting the API call to get schedule details - interceptGetScheduleDetailsApi(scheduleName); - // Listening for the browser confirm alert and confirming deletion - cy.expect_browser_confirm_with_text({ - confirmTriggerFn: () => selectConfigMenu(deleteScheduleConfigOption), - containsText: browserAlertDeleteConfirmText, + cy.interceptApi({ + alias: 'addScheduleApi', + urlPattern: '/ops/schedule_edit/new?button=save', + triggerFn: () => + cy + .getFormFooterButtonByType(SAVE_BUTTON_TEXT, 'submit') + .should('be.enabled') // Checks if Save button is enabled once all required fields are filled + .click(), + }); + return cy.then(() => { + return INITIAL_SCHEDULE_NAME; }); - cy.expect_flash(flashClassMap.success, flashMessageScheduleDeleted); } -function interceptGetScheduleDetailsApi(scheduleName = initialScheduleName) { +function clickScheduleItem(scheduleName) { + // TODO: Replace with cy.interceptApi after it's enhanced to wait conditionally on request trigger // Flag to check if the request is fired let requestFired = false; // Intercepting the API call @@ -181,7 +147,11 @@ function interceptGetScheduleDetailsApi(scheduleName = initialScheduleName) { ).as('getCreatedScheduleApi'); // Triggering the action that will fire the API call, // which is selecting the created schedule - cy.accordionItem(scheduleName); + cy.selectAccordionItem([ + MANAGEIQ_REGION_ACCORDION_ITEM, + SCHEDULES_ACCORDION_ITEM, + scheduleName, + ]); // Wait for the API call to complete if it was fired // This is to ensure that the test does not fail if the request was not fired cy.then(() => { @@ -192,249 +162,391 @@ function interceptGetScheduleDetailsApi(scheduleName = initialScheduleName) { }); } +function deleteSchedule(scheduleName) { + // Selecting the schedule and intercepting the API call to get schedule details + clickScheduleItem(scheduleName); + // Listening for the browser confirm alert and confirming deletion + cy.expect_browser_confirm_with_text({ + confirmTriggerFn: () => selectConfigMenu(DELETE_SCHEDULE_CONFIG_OPTION), + containsText: BROWSER_ALERT_DELETE_CONFIRM_TEXT, + }); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_SCHEDULE_DELETED); +} + function invokeCleanupDeletion() { // Iterate and clean up any leftover schedules created during the test - cy.get('li.list-group-item').each(($el) => { - const text = $el?.text()?.trim(); - if (text === initialScheduleName) { - deleteSchedule(); + cy.get('div.panel-collapse.collapse.in li.list-group-item').each((item) => { + const text = item?.text()?.trim(); + if (text === INITIAL_SCHEDULE_NAME) { + deleteSchedule(INITIAL_SCHEDULE_NAME); return false; } - if (text === editedScheduleName) { - deleteSchedule(editedScheduleName); - return false; + if (text === EDITED_SCHEDULE_NAME) { + deleteSchedule(EDITED_SCHEDULE_NAME); + return false; // exit iteration } - return true; + return null; // has no impact, just to get rid of eslint warning }); } -function verifyFilterTypeDropdownExists() { - cy.get('label[for="filter_typ"]').should('exist'); - cy.get('select#filter_typ').should('exist'); -} - -function verifyTimerDropdownExists() { - cy.get('label[for="timer_value"]').should('exist'); - cy.get('select#timer_value').should('exist'); -} - describe('Automate Schedule form operations: Settings > Application Settings > Settings > Schedules > Configuration > Add a new schedule', () => { beforeEach(() => { cy.login(); - cy.menu(settingsMenuOption, appSettingsMenuOption); - cy.intercept( - { - method: 'POST', - pathname: '/ops/tree_select', - query: { text: schedulesAccordionItem }, - }, - ).as('getSchedules'); - cy.accordionItem(schedulesAccordionItem); - cy.wait('@getSchedules'); + // Navigate to Application-Settings + cy.menu(SETTINGS_OPTION, APP_SETTINGS_OPTION); + // Expand Settings accordion panel + cy.accordion(SETTINGS_OPTION); + // Select Schedules accordion item + cy.interceptApi({ + alias: 'treeSelectApi', + urlPattern: /\/ops\/tree_select\?id=.*&text=.*/, + triggerFn: () => + cy.selectAccordionItem([ + MANAGEIQ_REGION_ACCORDION_ITEM, + SCHEDULES_ACCORDION_ITEM, + ]), + }); }); - it('Validate visibility of elements based on dropdown selections', () => { - selectConfigMenu(); + it('Validate visibility of elements and dynamic rendering based on dropdown changes', () => { + // Open add schedule form + selectConfigMenu(ADD_SCHEDULE_CONFIG_OPTION); + + // Assert basic info header is visible + cy.contains('h3', BASIC_INFO_SUB_HEADER).should('be.visible'); + // Assert name input field is visible & enabled + cy.getFormLabelByInputId('name') + .should('be.visible') + .and('contain.text', NAME_FIELD_LABEL); + cy.getFormInputFieldById('name').should('be.visible').and('be.enabled'); + // Assert description input field is visible & enabled + cy.getFormLabelByInputId('description') + .should('be.visible') + .and('contain.text', DESCRIPTION_FIELD_LABEL); + cy.getFormInputFieldById('description') + .should('be.visible') + .and('be.enabled'); + // Assert active checkbox field is visible & enabled + cy.getFormLabelByInputId('enabled') + .should('be.visible') + .and('contain.text', ACTIVE_CHECKBOX_FIELD_LABEL); + cy.getFormInputFieldById('enabled', 'checkbox') + .should('be.visible') + .and('be.enabled'); /* ===== Selecting any option other than "Automation Tasks" from "Action" dropdown does not hide the Filter dropdown ===== */ - - cy.get('select#action_typ').select(actionTypeVmAnalysis); - cy.get('select#action_typ').should('have.value', actionTypeVmAnalysis); - // Checking for Filter type dropdown - verifyFilterTypeDropdownExists(); - - cy.get('select#action_typ').select(actionTypeTemplateAnalysis); - cy.get('select#action_typ').should( - 'have.value', - actionTypeTemplateAnalysis + // Assert action type dropdown is visible & enabled and then selecting "Vm Analysis" to verify filter type dropdown is visible & enabled + cy.getFormLabelByInputId('action_typ') + .should('be.visible') + .and('contain.text', ACTION_TYPE_FIELD_LABEL); + cy.getFormSelectFieldById('action_typ') + .should('be.visible') + .and('be.enabled') + .select(ACTION_TYPE_VM_ANALYSIS); + cy.getFormLabelByInputId('filter_typ') + .should('be.visible') + .and('contain.text', FILTER_TYPE_FIELD_LABEL); + cy.getFormSelectFieldById('filter_typ') + .should('be.visible') + .and('be.enabled'); + // Selecting "Template Analysis" to verify filter type dropdown is visible & enabled + cy.getFormSelectFieldById('action_typ').select( + ACTION_TYPE_TEMPLATE_ANALYSIS ); - // Checking for Filter type dropdown - verifyFilterTypeDropdownExists(); - - cy.get('select#action_typ').select(actionTypeHostAnalysis); - cy.get('select#action_typ').should('have.value', actionTypeHostAnalysis); - // Checking for Filter type dropdown - verifyFilterTypeDropdownExists(); - - cy.get('select#action_typ').select(actionTypeContainerAnalysis); - cy.get('select#action_typ').should( - 'have.value', - actionTypeContainerAnalysis + cy.getFormLabelByInputId('filter_typ') + .should('be.visible') + .and('contain.text', FILTER_TYPE_FIELD_LABEL); + cy.getFormSelectFieldById('filter_typ') + .should('be.visible') + .and('be.enabled'); + // Selecting "Host Analysis" to verify filter type dropdown is visible & enabled + cy.getFormSelectFieldById('action_typ').select(ACTION_TYPE_HOST_ANALYSIS); + cy.getFormLabelByInputId('filter_typ') + .should('be.visible') + .and('contain.text', FILTER_TYPE_FIELD_LABEL); + cy.getFormSelectFieldById('filter_typ') + .should('be.visible') + .and('be.enabled'); + // Selecting "Container Analysis" to verify filter type dropdown is visible & enabled + cy.getFormSelectFieldById('action_typ').select( + ACTION_TYPE_CONTAINER_ANALYSIS ); - // Checking for Filter type dropdown - verifyFilterTypeDropdownExists(); - - cy.get('select#action_typ').select(actionTypeClusterAnalysis); - cy.get('select#action_typ').should('have.value', actionTypeClusterAnalysis); - // Checking for Filter type dropdown - verifyFilterTypeDropdownExists(); - - cy.get('select#action_typ').select(actionTypeDataStoreAnalysis); - cy.get('select#action_typ').should( - 'have.value', - actionTypeDataStoreAnalysis + cy.getFormLabelByInputId('filter_typ') + .should('be.visible') + .and('contain.text', FILTER_TYPE_FIELD_LABEL); + cy.getFormSelectFieldById('filter_typ') + .should('be.visible') + .and('be.enabled'); + // Selecting "Cluster Analysis" to verify filter type dropdown is visible & enabled + cy.getFormSelectFieldById('action_typ').select( + ACTION_TYPE_CLUSTER_ANALYSIS ); - // Checking for Filter type dropdown - verifyFilterTypeDropdownExists(); - - cy.get('select#action_typ').select(actionTypeVmCompilanceCheck); - cy.get('select#action_typ').should( - 'have.value', - actionTypeVmCompilanceCheck + cy.getFormLabelByInputId('filter_typ') + .should('be.visible') + .and('contain.text', FILTER_TYPE_FIELD_LABEL); + cy.getFormSelectFieldById('filter_typ') + .should('be.visible') + .and('be.enabled'); + // Selecting "DataStore Analysis" to verify filter type dropdown is visible & enabled + cy.getFormSelectFieldById('action_typ').select( + ACTION_TYPE_DATA_STORE_ANALYSIS ); - // Checking for Filter type dropdown - verifyFilterTypeDropdownExists(); - - cy.get('select#action_typ').select(actionTypeHostCompilanceCheck); - cy.get('select#action_typ').should( - 'have.value', - actionTypeHostCompilanceCheck + cy.getFormLabelByInputId('filter_typ') + .should('be.visible') + .and('contain.text', FILTER_TYPE_FIELD_LABEL); + cy.getFormSelectFieldById('filter_typ') + .should('be.visible') + .and('be.enabled'); + // Selecting "Vm Compilance Check" to verify filter type dropdown is visible & enabled + cy.getFormSelectFieldById('action_typ').select( + ACTION_TYPE_VM_COMPILANCE_CHECK ); - // Checking for Filter type dropdown - verifyFilterTypeDropdownExists(); - - cy.get('select#action_typ').select(actionTypeContainerCompilanceCheck); - cy.get('select#action_typ').should( - 'have.value', - actionTypeContainerCompilanceCheck + cy.getFormLabelByInputId('filter_typ') + .should('be.visible') + .and('contain.text', FILTER_TYPE_FIELD_LABEL); + cy.getFormSelectFieldById('filter_typ') + .should('be.visible') + .and('be.enabled'); + // Selecting "Host Compilance Check" to verify filter type dropdown is visible & enabled + cy.getFormSelectFieldById('action_typ').select( + ACTION_TYPE_HOST_COMPILANCE_CHECK ); - // Checking for Filter type dropdown - verifyFilterTypeDropdownExists(); + cy.getFormLabelByInputId('filter_typ') + .should('be.visible') + .and('contain.text', FILTER_TYPE_FIELD_LABEL); + cy.getFormSelectFieldById('filter_typ') + .should('be.visible') + .and('be.enabled'); + // Selecting "Container Compilance Check" to verify filter type dropdown is visible & enabled + cy.getFormSelectFieldById('action_typ').select( + ACTION_TYPE_CONTAINER_COMPILANCE_CHECK + ); + cy.getFormLabelByInputId('filter_typ') + .should('be.visible') + .and('contain.text', FILTER_TYPE_FIELD_LABEL); + cy.getFormSelectFieldById('filter_typ') + .should('be.visible') + .and('be.enabled'); /* ===== Selecting "Automation Tasks" option from "Action" dropdown shows Zone, Object details & Object fields ===== */ - - cy.get('select#action_typ').select(actionTypeAutomationTasks); - cy.get('select#action_typ').should('have.value', actionTypeAutomationTasks); - - // Checking for Zone dropdown - cy.get('label[for="zone_id"]').should('exist'); - cy.get('select#zone_id').should('exist'); - - // Checking for Object Details - cy.get('h3[name="object_details"]').should('exist'); - // Checking for System/Process dropdown - cy.get('label[for="instance_name"]').should('exist'); - cy.get('select#instance_name').should('exist'); - // Checking for Messsage textfield - cy.get('label[for="message"]').should('exist'); - cy.get('input#message').should('exist'); - // Checking for Request textfield - cy.get('label[for="request"]').should('exist'); - cy.get('input#request').should('exist'); - - // Checking for Object - cy.get('h3[name="object_attributes"]').should('exist'); - // Checking for Type Combobox - cy.get('label[for="target_class"]').should('exist'); - cy.get('input[role="combobox"]#target_class').should('exist'); - // Checking for Object Combobox - cy.get('label[for="target_id"]').should('exist'); - cy.get('input[role="combobox"]#target_id').should('exist'); - - // Checking for Attribute/Value pairs - cy.contains('h3', 'Attribute/Value Pairs').should('exist'); - // Checking for 5 attribute-value pairs text fields - cy.get('input#attribute_1').should('exist'); - cy.get('input#value_1').should('exist'); - cy.get('input#attribute_2').should('exist'); - cy.get('input#value_2').should('exist'); - cy.get('input#attribute_3').should('exist'); - cy.get('input#value_3').should('exist'); - cy.get('input#attribute_4').should('exist'); - cy.get('input#value_4').should('exist'); - cy.get('input#attribute_5').should('exist'); - cy.get('input#value_5').should('exist'); - - /* ===== Selecting "Once" option from "Run" dropdown does not show the "Every" dropdown ===== */ - - cy.get('select#timer_typ').select(timerTypeOnce); - // Checking whether the Every dropdown is hidden - cy.get('input#timer_value').should('not.exist'); - - /* ===== Selecting any other option other than "Once" from "Run" dropdown shows the "Every" dropdown ===== */ - - cy.get('select#timer_typ').select(timerTypeHourly); - // Checking whether the "Every" dropdown exist - verifyTimerDropdownExists(); - - cy.get('select#timer_typ').select(timerTypeDaily); - // Checking whether the "Every" dropdown exist - verifyTimerDropdownExists(); - - cy.get('select#timer_typ').select(timerTypeWeekly); - // Checking whether the "Every" dropdown exist - verifyTimerDropdownExists(); - - cy.get('select#timer_typ').select(timerTypeMonthly); - // Checking whether the "Every" dropdown exist - verifyTimerDropdownExists(); + cy.getFormSelectFieldById('action_typ').select( + ACTION_TYPE_AUTOMATION_TASKS + ); + // Assert Zone select field is visible & enabled + cy.getFormLabelByInputId('zone_id') + .should('be.visible') + .and('contain.text', ZONE_FIELD_LABEL); + cy.getFormSelectFieldById('zone_id').should('be.visible').and('be.enabled'); + + // Verifying Object Details fields + cy.contains('h3[name="object_details"]', OBJECT_DETAILS_SUB_HEADER).should( + 'be.visible' + ); + // Assert System/Process dropdown is visible & enabled + cy.getFormLabelByInputId('instance_name') + .should('be.visible') + .and('contain.text', SYSTEM_FIELD_LABEL); + cy.getFormSelectFieldById('instance_name') + .should('be.visible') + .and('be.enabled'); + // Assert Messsage input field is visible & enabled + cy.getFormLabelByInputId('message') + .should('be.visible') + .and('contain.text', MESSAGE_FIELD_LABEL); + cy.getFormInputFieldById('message').should('be.visible').and('be.enabled'); + // Assert Request input field is visible & enabled + cy.getFormLabelByInputId('request') + .should('be.visible') + .and('contain.text', REQUEST_FIELD_LABEL); + cy.getFormInputFieldById('request').should('be.visible').and('be.enabled'); + + // Verifying Object fields + cy.contains('h3[name="object_attributes"]', OBJECT_LABEL_TEXT).should( + 'be.visible' + ); + // Assert Type Combobox is visible & enabled and then selecting "Cloud Network" option + cy.getFormLabelByInputId('target_class') + .should('be.visible') + .and('contain.text', OBJECT_TYPE_FIELD_LABEL); + cy.getFormInputFieldById('target_class') + .should('be.visible') + .and('be.enabled') + .click(); + cy.contains('[role="option"]', OBJECT_TYPE_CLOUD_NETWORK).click(); + // Assert Object Combobox is visible & enabled, once Type is selected + cy.getFormLabelByInputId('target_id') + .should('be.visible') + .and('contain.text', OBJECT_LABEL_TEXT); + cy.getFormInputFieldById('target_id') + .should('be.visible') + .and('be.enabled'); + + // Verifying Attribute/Value pairs fields + cy.contains('h3', ATTRIBUTE_PAIRS_SUB_HEADER).should('be.visible'); + // Verifying 5 attribute-value pairs text fields are visible and enabled + cy.getFormInputFieldById('attribute_1') + .should('be.visible') + .and('be.enabled'); + cy.getFormInputFieldById('value_1').should('be.visible').and('be.enabled'); + cy.getFormInputFieldById('attribute_2') + .should('be.visible') + .and('be.enabled'); + cy.getFormInputFieldById('value_2').should('be.visible').and('be.enabled'); + cy.getFormInputFieldById('attribute_3') + .should('be.visible') + .and('be.enabled'); + cy.getFormInputFieldById('value_3').should('be.visible').and('be.enabled'); + cy.getFormInputFieldById('attribute_4') + .should('be.visible') + .and('be.enabled'); + cy.getFormInputFieldById('value_4').should('be.visible').and('be.enabled'); + cy.getFormInputFieldById('attribute_5') + .should('be.visible') + .and('be.enabled'); + cy.getFormInputFieldById('value_5').should('be.visible').and('be.enabled'); + + /* ===== Selecting "Once" option from "Run" dropdown should not show "Every" dropdown ===== */ + // Assert Run(timer type) dropdown is visible & enabled and then selecting "Once" option + cy.getFormLabelByInputId('timer_typ') + .should('be.visible') + .and('contain.text', TIMER_TYPE_FIELD_LABEL); + cy.getFormSelectFieldById('timer_typ') + .should('be.visible') + .and('be.enabled') + .select(TIMER_TYPE_ONCE); + // Assert "Every" dropdown is hidden + cy.getFormInputFieldById('timer_value').should('not.exist'); + + /* ===== Selecting any other option other than "Once" from "Run" dropdown should show "Every" dropdown ===== */ + // Selecting "Hourly" to verify timer dropdown is visible & enabled + cy.getFormSelectFieldById('timer_typ').select(TIMER_TYPE_HOURLY); + cy.getFormLabelByInputId('timer_value') + .should('be.visible') + .and('contain.text', TIMER_VALUE_FIELD_LABEL); + cy.getFormSelectFieldById('timer_value') + .should('be.visible') + .and('be.enabled'); + // Selecting "Daily" to verify timer dropdown is visible & enabled + cy.getFormSelectFieldById('timer_typ').select(TIMER_TYPE_DAILY); + cy.getFormLabelByInputId('timer_value') + .should('be.visible') + .and('contain.text', TIMER_VALUE_FIELD_LABEL); + cy.getFormSelectFieldById('timer_value') + .should('be.visible') + .and('be.enabled'); + // Selecting "Weekly" to verify timer dropdown is visible & enabled + cy.getFormSelectFieldById('timer_typ').select(TIMER_TYPE_WEEKLY); + cy.getFormLabelByInputId('timer_value') + .should('be.visible') + .and('contain.text', TIMER_VALUE_FIELD_LABEL); + cy.getFormSelectFieldById('timer_value') + .should('be.visible') + .and('be.enabled'); + // Selecting "Monthly" to verify timer dropdown is visible & enabled + cy.getFormSelectFieldById('timer_typ').select(TIMER_TYPE_MONTHLY); + cy.getFormLabelByInputId('timer_value') + .should('be.visible') + .and('contain.text', TIMER_VALUE_FIELD_LABEL); + cy.getFormSelectFieldById('timer_value') + .should('be.visible') + .and('be.enabled'); + + // Assert timezone dropdown is visible & enabled + cy.getFormLabelByInputId('time_zone') + .should('be.visible') + .and('contain.text', TIME_ZONE_FIELD_LABEL); + cy.getFormInputFieldById('time_zone') + .should('be.visible') + .and('be.enabled'); + // Assert starting date field is visible & enabled + cy.getFormLabelByInputId('start_date') + .should('be.visible') + .and('contain.text', START_DATE_FIELD_LABEL); + cy.getFormInputFieldById('start_date') + .should('be.visible') + .and('be.enabled'); + // Assert starting time field is visible & enabled + cy.getFormLabelByInputId('start_time') + .should('be.visible') + .and('contain.text', START_TIME_FIELD_LABEL); + cy.getFormInputFieldById('start_time') + .should('be.visible') + .and('be.enabled'); + // Assert save button is visible and disabled + cy.getFormFooterButtonByType(SAVE_BUTTON_TEXT, 'submit') + .should('be.visible') + .and('be.disabled'); + // Assert cancel button is visible and enabled + cy.getFormFooterButtonByType(CANCEL_BUTTON_TEXT) + .should('be.visible') + .and('be.enabled'); }); it('Checking whether Cancel button works on the Add form', () => { - selectConfigMenu(); - cy.contains( - '#main-content .bx--btn-set button[type="button"]', - cancelButton - ) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, flashMessageOperationCanceled); + // Open add schedule form + selectConfigMenu(ADD_SCHEDULE_CONFIG_OPTION); + // Cancel the form + cy.getFormFooterButtonByType(CANCEL_BUTTON_TEXT).click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_CANCELED); }); it('Checking whether add, edit & delete schedule works', () => { /* ===== Adding a schedule ===== */ - addSchedule(); - cy.expect_flash(flashClassMap.success, flashMessageScheduleSaved); + addSchedule().then((createdScheduleName) => { + // createdScheduleName value will be "Test-name" + // Assert schedule saved flash message + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_SCHEDULE_SAVED); + // Selecting the schedule and intercepting the API call to get schedule details + clickScheduleItem(createdScheduleName); + }); /* ===== Editing a schedule ===== */ - // Selecting the schedule and intercepting the API call to get schedule details - interceptGetScheduleDetailsApi(); - selectConfigMenu(editScheduleConfigOption); + // Open edit schedule form + selectConfigMenu(EDIT_SCHEDULE_CONFIG_OPTION); // Editing name and description - cy.get('input#name').clear().type(editedScheduleName); - cy.get('input#description').clear().type(editedDescription); + cy.getFormInputFieldById('name').clear().type(EDITED_SCHEDULE_NAME); + cy.getFormInputFieldById('description').clear().type(EDITED_DESCRIPTION); // Confirms Save button is enabled after making edits - cy.contains('#main-content .bx--btn-set button[type="submit"]', saveButton) + cy.getFormFooterButtonByType(SAVE_BUTTON_TEXT, 'submit') .should('be.enabled') .click(); - cy.expect_flash(flashClassMap.success, flashMessageScheduleSaved); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_SCHEDULE_SAVED); /* ===== Delete is already handled from afterEach hook ===== */ }); it('Checking whether Cancel & Reset buttons work fine in the Edit form', () => { /* ===== Adding a schedule ===== */ - addSchedule(); - - /* ===== Checking whether Cancel button works ===== */ - // Selecting the schedule and intercepting the API call to get schedule details - interceptGetScheduleDetailsApi(); - selectConfigMenu(editScheduleConfigOption); - cy.contains( - '#main-content .bx--btn-set button[type="button"]', - cancelButton - ) - .should('be.enabled') - .click(); - cy.expect_flash(flashClassMap.success, flashMessageOperationCanceled); + addSchedule().then((createdScheduleName) => { + // createdScheduleName value will be "Test-name" + // Selecting the schedule and intercepting the API call to get schedule details + clickScheduleItem(createdScheduleName); + }); /* ===== Checking whether Reset button works ===== */ - // Selecting the schedule and intercepting the API call to get schedule details - interceptGetScheduleDetailsApi(); - selectConfigMenu(editScheduleConfigOption); + // Open edit schedule form + selectConfigMenu(EDIT_SCHEDULE_CONFIG_OPTION); // Editing description and start date - cy.get('input#description').clear().type(editedDescription); - cy.get('input#start_date').clear().type(editedStartDate); - cy.contains('#main-content .bx--btn-set button[type="button"]', resetButton) + cy.getFormInputFieldById('description').clear().type(EDITED_DESCRIPTION); + cy.getFormInputFieldById('start_date').clear().type(EDITED_START_DATE); + // Resetting + cy.getFormFooterButtonByType(RESET_BUTTON_TEXT) .should('be.enabled') .click(); - cy.expect_flash(flashClassMap.warning, flashMessageResetSchedule); + cy.expect_flash(flashClassMap.warning, FLASH_MESSAGE_RESET_SCHEDULE); // Confirming the edited fields contain the old values after resetting - cy.get('input#description').should('have.value', initialDescription); - cy.get('input#start_date').should('have.value', initialStartDate); + cy.getFormInputFieldById('description').should( + 'have.value', + INITIAL_DESCRIPTION + ); + cy.getFormInputFieldById('start_date').should( + 'have.value', + INITIAL_START_DATE + ); - // Selecting Schedules menu item to bypass a bug, can be removed once #9505 is merged - cy.accordionItem(schedulesAccordionItem); + /* ===== Checking whether Cancel button works ===== */ + cy.getFormFooterButtonByType(CANCEL_BUTTON_TEXT).click(); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_CANCELED); }); it('Checking whether creating a duplicate record is restricted', () => { @@ -443,38 +555,39 @@ describe('Automate Schedule form operations: Settings > Application Settings > S /* ===== Trying to add the same schedule again ===== */ addSchedule(); - cy.expect_flash(flashClassMap.error, flashMessageFailedToAddSchedule); + cy.expect_flash(flashClassMap.error, FLASH_MESSAGE_FAILED_TO_ADD_SCHEDULE); }); it('Checking whether Disabling, Enabling & Queueing up the schedule works', () => { /* ===== Adding a schedule ===== */ addSchedule(); // Selecting the schedule and intercepting the API call to get schedule details - interceptGetScheduleDetailsApi(); + clickScheduleItem(INITIAL_SCHEDULE_NAME); /* ===== Disabling the schedule ===== */ - selectConfigMenu(disableScheduleConfigOption); - cy.expect_flash(flashClassMap.info, flashMessageScheduleDisabled); + selectConfigMenu(DISABLE_SCHEDULE_CONFIG_OPTION); + cy.expect_flash(flashClassMap.info, FLASH_MESSAGE_SCHEDULE_DISABLED); /* ===== Enabling the schedule ===== */ - selectConfigMenu(enableScheduleConfigOption); - cy.expect_flash(flashClassMap.info, flashMessageScheduleEnabled); + selectConfigMenu(ENABLE_SCHEDULE_CONFIG_OPTION); + cy.expect_flash(flashClassMap.info, FLASH_MESSAGE_SCHEDULE_ENABLED); /* ===== Queueing-up the schedule ===== */ - selectConfigMenu(queueScheduleConfigOption); - cy.expect_flash(flashClassMap.success, flashMessageScheduleQueued); + selectConfigMenu(QUEUE_SCHEDULE_CONFIG_OPTION); + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_SCHEDULE_QUEUED); }); afterEach(() => { - cy?.url()?.then((url) => { - // Ensures navigation to Settings -> Application-Settings in the UI - if (url?.includes('/ops/explorer')) { - invokeCleanupDeletion(); - } else { - // Navigate to Settings -> Application-Settings before looking out for Schedules created during test - cy.menu(settingsMenuOption, appSettingsMenuOption); + cy.url() + ?.then((url) => { + // Ensures navigation to Settings -> Application-Settings in the UI + if (!url?.includes(COMPONENT_ROUTE_URL)) { + // Navigate to Settings -> Application-Settings before looking out for Schedules created during test + cy.menu(SETTINGS_OPTION, APP_SETTINGS_OPTION); + } + }) + .then(() => { invokeCleanupDeletion(); - } - }); + }); }); });