From 00fd83e1a412407d4126e974c576c1acc92f8e25 Mon Sep 17 00:00:00 2001 From: asirvadAbrahamVarghese Date: Wed, 27 Aug 2025 09:46:16 +0530 Subject: [PATCH 1/5] Enhanced element selector commands for improved readability --- .../edit_collect_logs.cy.js | 67 ++++++++++----- .../settings_access_control.cy.js | 13 ++- cypress/support/commands/element_selectors.js | 85 +++++++++++++------ 3 files changed, 114 insertions(+), 51 deletions(-) diff --git a/cypress/e2e/ui/Settings/Application-Settings/edit_collect_logs.cy.js b/cypress/e2e/ui/Settings/Application-Settings/edit_collect_logs.cy.js index 68d12f725d8..0b726bb569f 100644 --- a/cypress/e2e/ui/Settings/Application-Settings/edit_collect_logs.cy.js +++ b/cypress/e2e/ui/Settings/Application-Settings/edit_collect_logs.cy.js @@ -66,16 +66,21 @@ function resetProtocolDropdown({ selectServerListItem = true } = {}) { selectToolbarEditButton(); // Resetting Protocol dropdown value - cy.getFormSelectFieldById('log_protocol').then((selectField) => { - const currentValue = selectField.val(); - // If the value is not default one(BLANK_VALUE), then setting it to blank - if (currentValue !== DROPDOWN_BLANK_VALUE) { - cy.wrap(selectField).select(DROPDOWN_BLANK_VALUE); - cy.getFormFooterButtonByType(SAVE_BUTTON_TEXT, 'submit').click(); - // Validating confirmation flash message - cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_SETTINGS_SAVED); + cy.getFormSelectFieldById({ selectId: 'log_protocol' }).then( + (selectField) => { + const currentValue = selectField.val(); + // If the value is not default one(BLANK_VALUE), then setting it to blank + if (currentValue !== DROPDOWN_BLANK_VALUE) { + cy.wrap(selectField).select(DROPDOWN_BLANK_VALUE); + cy.getFormFooterButtonByTypeWithText({ + buttonText: SAVE_BUTTON_TEXT, + buttonType: 'submit', + }).click(); + // Validating confirmation flash message + cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_SETTINGS_SAVED); + } } - }); + ); } function goToCollectLogsTabAndOpenEditForm() { @@ -93,39 +98,56 @@ function validateFormElements() { 'be.visible' ); // Assert protocol field label is visible - cy.getFormLabelByInputId('log_protocol').should('be.visible'); + cy.getFormLabelByForAttribute({ forValue: 'log_protocol' }).should( + 'be.visible' + ); // Assert protocol field is visible and enabled - cy.getFormSelectFieldById('log_protocol') + cy.getFormSelectFieldById({ selectId: 'log_protocol' }) .should('be.visible') .and('be.enabled'); // Assert cancel button is visible and enabled - cy.getFormFooterButtonByType(CANCEL_BUTTON_TEXT) + cy.getFormFooterButtonByTypeWithText({ + buttonText: CANCEL_BUTTON_TEXT, + }) .should('be.visible') .and('be.enabled'); // Assert save button is visible and disabled - cy.getFormFooterButtonByType(SAVE_BUTTON_TEXT, 'submit') + cy.getFormFooterButtonByTypeWithText({ + buttonText: SAVE_BUTTON_TEXT, + buttonType: 'submit', + }) .should('be.visible') .and('be.disabled'); // Assert reset button is visible and disabled - cy.getFormFooterButtonByType(RESET_BUTTON_TEXT) + cy.getFormFooterButtonByTypeWithText({ + buttonText: RESET_BUTTON_TEXT, + }) .should('be.visible') .and('be.disabled'); } function cancelButtonValidation() { // Click cancel button in the form - cy.getFormFooterButtonByType(CANCEL_BUTTON_TEXT).click(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: CANCEL_BUTTON_TEXT, + }).click(); // Validating confirmation flash message cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_CANCELLED); } function resetButtonValidation() { // Selecting Samba option from dropdown - cy.getFormSelectFieldById('log_protocol').select(SAMBA_DROPDOWN_VALUE); + cy.getFormSelectFieldById({ selectId: 'log_protocol' }).select( + SAMBA_DROPDOWN_VALUE + ); // Confirm Reset button is enabled once dropdown value is changed and then click on Reset - cy.getFormFooterButtonByType(RESET_BUTTON_TEXT).should('be.enabled').click(); + cy.getFormFooterButtonByTypeWithText({ + buttonText: RESET_BUTTON_TEXT, + }) + .should('be.enabled') + .click(); // Confirm dropdown has the old value - cy.getFormSelectFieldById('log_protocol').should( + cy.getFormSelectFieldById({ selectId: 'log_protocol' }).should( 'have.value', DROPDOWN_BLANK_VALUE ); @@ -133,9 +155,14 @@ function resetButtonValidation() { function saveButtonValidation() { // Selecting Samba option from dropdown - cy.getFormSelectFieldById('log_protocol').select(SAMBA_DROPDOWN_VALUE); + cy.getFormSelectFieldById({ selectId: 'log_protocol' }).select( + SAMBA_DROPDOWN_VALUE + ); // Confirm Save button is enabled once dropdown value is changed and then click on Save - cy.getFormFooterButtonByType(SAVE_BUTTON_TEXT, 'submit') + cy.getFormFooterButtonByTypeWithText({ + buttonText: SAVE_BUTTON_TEXT, + buttonType: 'submit', + }) .should('be.enabled') .click(); // Validating confirmation flash message diff --git a/cypress/e2e/ui/Settings/Application-Settings/settings_access_control.cy.js b/cypress/e2e/ui/Settings/Application-Settings/settings_access_control.cy.js index 33ea04a4458..2ef62ed3538 100644 --- a/cypress/e2e/ui/Settings/Application-Settings/settings_access_control.cy.js +++ b/cypress/e2e/ui/Settings/Application-Settings/settings_access_control.cy.js @@ -31,9 +31,16 @@ describe('Settings > Application Settings > Access Control', () => { ]); cy.toolbar(TOOLBAR_MENU, 'Add child Tenant to this Tenant'); - cy.getFormInputFieldById('name').type(INITIAL_TENANT_NAME); - cy.getFormInputFieldById('description').type(INITIAL_TENANT_DESCRIPTION); - cy.getFormFooterButtonByType('Add', 'submit').click(); + cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type( + INITIAL_TENANT_NAME + ); + cy.getFormInputFieldByIdAndType({ inputId: 'description' }).type( + INITIAL_TENANT_DESCRIPTION + ); + cy.getFormFooterButtonByTypeWithText({ + buttonText: 'Add', + buttonType: 'submit', + }).click(); cy.expect_flash(flashClassMap.success, FLASH_MESSAGE_OPERATION_ADDED); cy.selectAccordionItem([ /^ManageIQ Region/, diff --git a/cypress/support/commands/element_selectors.js b/cypress/support/commands/element_selectors.js index 46194e01232..b6d84c268c3 100644 --- a/cypress/support/commands/element_selectors.js +++ b/cypress/support/commands/element_selectors.js @@ -1,57 +1,86 @@ -/* eslint-disable no-undef */ - /** - * Retrieves a form footer button by its name and type. + * Retrieves a form footer button by its text content and type using an object parameter. * - * @param {string} name - The name or text content of the button. - * @param {string} [type='button'] - The HTML button type (e.g., 'button', 'submit', 'reset'). Defaults to 'button'. + * @param {Object} options - The options object. + * @param {string} options.buttonText - The text content of the button (required). + * @param {string} [options.buttonType='button'] - The HTML button type (e.g., 'button', 'submit', 'reset'). Defaults to 'button'. * @returns {Element} The matched button element. + * @throws {Error} If buttonName is not provided. * * Example: - * cy.getFormFooterButtonByType('Save Changes'); - * cy.getFormFooterButtonByType('Reset', 'reset'); + * cy.getFormFooterButtonByTypeWithText({ buttonText: 'Save Changes' }); + * cy.getFormFooterButtonByTypeWithText({ buttonText: 'Submit', buttonType: 'submit' }); */ -Cypress.Commands.add('getFormFooterButtonByType', (name, type = 'button') => - cy.contains(`#main-content .bx--btn-set button[type="${type}"]`, name) +Cypress.Commands.add( + 'getFormFooterButtonByTypeWithText', + ({ buttonType = 'button', buttonText } = {}) => { + if (!buttonText) { + cy.logAndThrowError('buttonName is required'); + } + return cy.contains( + `#main-content .bx--btn-set button[type="${buttonType}"]`, + buttonText + ); + } ); /** - * Retrieves a form input field by its ID and type. + * Retrieves a form input field by its ID and type using an object parameter. * - * @param {string} inputId - The ID of the input field. - * @param {string} [type='text'] - The HTML input type (e.g., 'text', 'email', 'password'). Defaults to 'text'. + * @param {Object} options - The options object. + * @param {string} options.inputId - The ID of the input field (required). + * @param {string} [options.inputType='text'] - The HTML input inputType (e.g., 'text', 'email', 'password'). Defaults to 'text'. * @returns {Element} The matched input field element. + * @throws {Error} If inputId is not provided. * * Example: - * cy.getFormInputFieldById('name'); - * cy.getFormInputFieldById('name', 'text'); + * cy.getFormInputFieldByIdAndType({ inputId: 'name' }); + * cy.getFormInputFieldByIdAndType({ inputId: 'password', inputType: 'password' }); */ -Cypress.Commands.add('getFormInputFieldById', (inputId, type = 'text') => - cy.get(`#main-content .bx--form input#${inputId}[type="${type}"]`) +Cypress.Commands.add( + 'getFormInputFieldByIdAndType', + ({ inputId, inputType = 'text' }) => { + if (!inputId) { + cy.logAndThrowError('inputId is required'); + } + return cy.get( + `#main-content .bx--form input#${inputId}][type="${inputType}"]` + ); + } ); /** - * Retrieves a form label associated with a specific input field by its ID. + * Retrieves a form label associated with a specific input field by its 'for' attribute. * - * @param {string} inputId - The ID of the input field. + * @param {Object} options - The options object. + * @param {string} options.forValue - The value of the 'for' attribute that matches the input field's ID (required). * @returns {Element} The matched label element. + * @throws {Error} If forValue is not provided. * * Example: - * cy.getFormLabelByInputId('name'); + * cy.getFormLabelByForAttribute({ forValue: 'name' }); */ -Cypress.Commands.add('getFormLabelByInputId', (inputId) => - cy.get(`#main-content .bx--form label[for="${inputId}"]`) -); +Cypress.Commands.add('getFormLabelByForAttribute', ({ forValue }) => { + if (!forValue) { + cy.logAndThrowError('forValue is required'); + } + return cy.get(`#main-content .bx--form label[for="${forValue}"]`); +}); /** - * Retrieves a form select field by its ID. + * Retrieves a form select field by its ID using an object parameter. * - * @param {string} selectId - The ID of the select field. + * @param {Object} options - The options object. + * @param {string} options.selectId - The ID of the select field (required). * @returns {Element} The matched select field element. + * @throws {Error} If selectId is not provided. * * Example: - * cy.getFormSelectFieldById('select-scan-limit'); + * cy.getFormSelectFieldById({ selectId: 'select-scan-limit' }); */ -Cypress.Commands.add('getFormSelectFieldById', (selectId) => - cy.get(`#main-content .bx--form select#${selectId}`) -); +Cypress.Commands.add('getFormSelectFieldById', ({ selectId }) => { + if (!selectId) { + cy.logAndThrowError('selectId is required'); + } + return cy.get(`#main-content .bx--form select#${selectId}]`); +}); From 72cf661360b00f2ad08db378c2e460160d1a6a21 Mon Sep 17 00:00:00 2001 From: asirvadAbrahamVarghese Date: Wed, 27 Aug 2025 09:47:47 +0530 Subject: [PATCH 2/5] Revised element_selectors section in README --- cypress/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cypress/README.md b/cypress/README.md index 47e7a04bc49..670fd0188ab 100644 --- a/cypress/README.md +++ b/cypress/README.md @@ -74,10 +74,10 @@ ManageIQ implements the following cypress extensions: ##### element_selectors -* `cy.getFormFooterButtonByType(name, type)` - retrieves form footer button by its name and type. `name` is the name or text content of the button. `type` is the HTML button type (e.g., 'button', 'submit', 'reset'). Defaults to 'button'. e.g. `cy.getFormFooterButtonByType('Save');`, `cy.getFormFooterButtonByType('Reset', 'reset');` -* `cy.getFormInputFieldById(inputId, type)` - retrieves a form input field by its ID and type. `inputId` is the ID of the input field. `type` is the HTML input type (e.g., 'text', 'email', 'password'). Defaults to 'text'. e.g. `cy.getFormInputFieldById('name');`, `cy.getFormInputFieldById('name', 'text');` -* `getFormLabelByInputId(inputId)` - retrieves a form label associated with a specific input field by its ID. `inputId` is the ID of the input field. e.g. `cy.getFormLabelByInputId('name');` -* `cy.getFormSelectFieldById(selectId)` - retrieves a form select field by its ID. `selectId` is the ID of the select field. e.g. `cy.getFormSelectFieldById('select-scan-limit');` +* `cy.getFormFooterButtonByTypeWithText({ buttonType, buttonText })` - retrieves form footer button by its name and type. `buttonText` is the name or text content of the button. `buttonType` is the HTML button type (e.g., 'button', 'submit', 'reset'). Defaults to 'button'. e.g. `cy.getFormFooterButtonByType({buttonType: 'Reset', buttonText: 'reset'});`, `cy.getFormFooterButtonByTypeWithText({buttonText: 'Cancel'});` +* `cy.getFormInputFieldByIdAndType({ inputId, inputType })` - retrieves a form input field by its ID and type. `inputId` is the ID of the input field. `inputType` is the HTML input type (e.g., 'text', 'email', 'password'). Defaults to 'text'. e.g. `cy.getFormInputFieldByIdAndType({inputId: 'name'});`, `cy.getFormInputFieldByIdAndType({inputId: 'name', inputType: 'text'});` +* `cy.getFormLabelByForAttribute({ forValue })` - retrieves a form label associated with a specific input field by its 'for' attribute. `forValue` is the value of the 'for' attribute that matches the input field's ID. e.g. `cy.getFormLabelByForAttribute({forValue: 'name'});` +* `cy.getFormSelectFieldById({ selectId })` - retrieves a form select field by its ID. `selectId` is the ID of the select field. e.g. `cy.getFormSelectFieldById({selectId: 'select-scan-limit'});` #### Assertions From 4bf8dcbf5d8468ea798c5da7d3f466869ed63ebd Mon Sep 17 00:00:00 2001 From: asirvadAbrahamVarghese Date: Mon, 8 Sep 2025 15:33:48 +0530 Subject: [PATCH 3/5] Selecting by ID through attribute syntax --- cypress/support/commands/element_selectors.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cypress/support/commands/element_selectors.js b/cypress/support/commands/element_selectors.js index b6d84c268c3..1d4ae0eebea 100644 --- a/cypress/support/commands/element_selectors.js +++ b/cypress/support/commands/element_selectors.js @@ -44,7 +44,7 @@ Cypress.Commands.add( cy.logAndThrowError('inputId is required'); } return cy.get( - `#main-content .bx--form input#${inputId}][type="${inputType}"]` + `#main-content .bx--form input[id="${inputId}"][type="${inputType}"]` ); } ); @@ -82,5 +82,5 @@ Cypress.Commands.add('getFormSelectFieldById', ({ selectId }) => { if (!selectId) { cy.logAndThrowError('selectId is required'); } - return cy.get(`#main-content .bx--form select#${selectId}]`); + return cy.get(`#main-content .bx--form select[id="${selectId}"]`); }); From 0c0b9639b0b9b1e47a4bd288011d2ed51794fad4 Mon Sep 17 00:00:00 2001 From: asirvadAbrahamVarghese Date: Wed, 10 Sep 2025 11:01:37 +0530 Subject: [PATCH 4/5] Added custom selector for form textarea element --- cypress/support/commands/element_selectors.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cypress/support/commands/element_selectors.js b/cypress/support/commands/element_selectors.js index 1d4ae0eebea..753f7dbe95b 100644 --- a/cypress/support/commands/element_selectors.js +++ b/cypress/support/commands/element_selectors.js @@ -84,3 +84,21 @@ Cypress.Commands.add('getFormSelectFieldById', ({ selectId }) => { } return cy.get(`#main-content .bx--form select[id="${selectId}"]`); }); + +/** + * Retrieves a form textarea field by its ID using an object parameter. + * + * @param {Object} options - The options object. + * @param {string} options.textareaId - The ID of the textarea field (required). + * @returns {Element} The matched textarea field element. + * @throws {Error} If textareaId is not provided. + * + * Example: + * cy.getFormTextareaById({ textareaId: 'default.auth_key' }); + */ +Cypress.Commands.add('getFormTextareaById', ({ textareaId }) => { + if (!textareaId) { + cy.logAndThrowError('textareaId is required'); + } + return cy.get(`#main-content .bx--form textarea[id="${textareaId}"]`); +}); From 84dcf23d76b9d2afc33592b41f5f647456b7f7e5 Mon Sep 17 00:00:00 2001 From: asirvadAbrahamVarghese Date: Wed, 10 Sep 2025 11:03:02 +0530 Subject: [PATCH 5/5] Included textarea selector command in README --- cypress/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/cypress/README.md b/cypress/README.md index 670fd0188ab..8ebe2607d28 100644 --- a/cypress/README.md +++ b/cypress/README.md @@ -78,6 +78,7 @@ ManageIQ implements the following cypress extensions: * `cy.getFormInputFieldByIdAndType({ inputId, inputType })` - retrieves a form input field by its ID and type. `inputId` is the ID of the input field. `inputType` is the HTML input type (e.g., 'text', 'email', 'password'). Defaults to 'text'. e.g. `cy.getFormInputFieldByIdAndType({inputId: 'name'});`, `cy.getFormInputFieldByIdAndType({inputId: 'name', inputType: 'text'});` * `cy.getFormLabelByForAttribute({ forValue })` - retrieves a form label associated with a specific input field by its 'for' attribute. `forValue` is the value of the 'for' attribute that matches the input field's ID. e.g. `cy.getFormLabelByForAttribute({forValue: 'name'});` * `cy.getFormSelectFieldById({ selectId })` - retrieves a form select field by its ID. `selectId` is the ID of the select field. e.g. `cy.getFormSelectFieldById({selectId: 'select-scan-limit'});` +* `cy.getFormTextareaById({ textareaId })` - retrieves a form textarea field by its ID. `textareaId` is the ID of the textarea field. e.g. `cy.getFormTextareaById({textareaId: 'default.auth_key'});` #### Assertions