Skip to content

Conversation

asirvadAbrahamVarghese
Copy link
Contributor

@asirvadAbrahamVarghese asirvadAbrahamVarghese commented Jul 29, 2025

CP4AIOPS-16943
Pr that adds cypress tests for Tenants form(Settings -> Application Settings ->Access Control -> Tenants)

  • Edit parent tenant
  • Add project to parent tenant
  • Manage quotas with parent tenant
  • Add, edit and delete child tenant
  • Add project to child tenant
  • Manage quotas with child tenant

@miq-bot assign @elsamaryv
@miq-bot add-label cypress
@miq-bot add-label test

@asirvadAbrahamVarghese asirvadAbrahamVarghese requested a review from a team as a code owner July 29, 2025 13:11
@asirvadAbrahamVarghese asirvadAbrahamVarghese force-pushed the tenants-form-automation-testing branch from fe71238 to 3cdea0a Compare July 29, 2025 14:07
@asirvadAbrahamVarghese
Copy link
Contributor Author

Sporadic server-related failures were noticed here as well:
image

A couple of API requests are made right after logging in, prior to dashboard rendering:
image

So I just tried adding a fixed wait using cy.wait immediately after login, before moving to the menu, which seems to help stabilize the test with fewer sporadic failures
CI Runs with wait:
attempt-1
image
attempt-2
image

CI run without wait
image

@asirvadAbrahamVarghese
Copy link
Contributor Author

Need a second opinion here -

This test currently bundles add project and manage quotas with both parent and child tenants, which makes it quite large. Would it be better to break out add project and manage quotas into standalone tests?

@asirvadAbrahamVarghese
Copy link
Contributor Author

asirvadAbrahamVarghese commented Jul 29, 2025

TODOs:

@jrafanie
Copy link
Member

RE: the sporadic test failure... see #9515 (comment) (if we can bypass saving session in the API and some of the /dashboard GETs, most of the contention causing stale session writes should be removed. 🤞

@asirvadAbrahamVarghese asirvadAbrahamVarghese changed the title Added automated tests with cypress for Tenants form [WIP] - Added automated tests with cypress for Tenants form Aug 6, 2025
@asirvadAbrahamVarghese asirvadAbrahamVarghese force-pushed the tenants-form-automation-testing branch from 3cdea0a to f3ec47a Compare August 6, 2025 19:21
@asirvadAbrahamVarghese
Copy link
Contributor Author

Related issue on tenant deletion: #9512

@asirvadAbrahamVarghese asirvadAbrahamVarghese force-pushed the tenants-form-automation-testing branch 2 times, most recently from 339c7eb to 42fcdcf Compare August 7, 2025 09:34

it('Validate Cancel & Reset buttons in Manage Quotas form', () => {
// Edit the quotas table and reset the quotas
quotasResetOperation();
Copy link
Member

@jrafanie jrafanie Aug 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This quotasResetOperation function combines the navigate to the form, editing it, clicking a button and validating the flash/result. I think these would read better if the tests read like this:

  cy.getFormFooterButtonByType(resetButton, resetButtonType).should(
    'be.disabled'
  );

  // Editing the quota table
  editQuotasTable(quotaName);

  cy.getFormFooterButtonByType(resetButton, resetButtonType)
    .should('be.enabled')
    .click();
  cy.expect_flash(flashTypeWarning, flashMessageOperationReset);
  cancelOperation();

Copy link
Contributor Author

@asirvadAbrahamVarghese asirvadAbrahamVarghese Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inlined the logic and removed the quotasResetOperation method for improved readability - here & here


it('Validate Manage Quotas function', () => {
// Enabling the quota: "Allocated Storage in GB" with value 10
updateQuotas();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, I need to scroll to the function to understand what's being done and then asserted.

I don't mind repeating the same code if it better describes the test:

  editQuotasTable(quotaName);
  // Saving the form
  cy.getFormFooterButtonByType(saveButton, submitButtonType).click();
  cy.expect_flash(flashTypeSuccess, flashMessageSaved);

Copy link
Contributor Author

@asirvadAbrahamVarghese asirvadAbrahamVarghese Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the updateQuotas method & inlined the logic for improved readability - here & here


it('Validate cancel button on Add child tenant form', () => {
// Cancel the add operation
cancelOperation();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if this is worthy of a separate test. It's also called on line 441.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we cancel the form and also assert the flash message, but on 441 the form is cancelled after checking an inline error, and no flash message needs to be asserted so I've handled that with a flag making the method more versatile(see).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarification. Basically, if we have a single step test, we should verify if it's really within a larger workflow. It's ok to unit test in cypress but I think something like cancel would be better suited towards filling out the minimum needed for a form but then hitting cancel. Or mix it with "click add child tenant", "cancel", click it again, fill out the form and save/add.

Copy link
Contributor Author

@asirvadAbrahamVarghese asirvadAbrahamVarghese Aug 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, mixed it with "add & delete child tenant" test - see


it('Validate Cancel & Reset buttons on Edit tenant form', () => {
// Reset operation
resetOperation();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to above, this function is doing more than one thing. I think it would read better as a test:

verify reset disabled
edit form
verify reset enabled / any other validations

Copy link
Contributor Author

@asirvadAbrahamVarghese asirvadAbrahamVarghese Aug 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done here & here

});

after(() => {
confirmUiNavigation(() => deleteAccordionItem(projectNameValue));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar here... single after call... wondering if we could have a problem if the test were run out of order in a specific order.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh wait, is after an alias for afterEach?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the suite 'Validate Add Project function' has only one test, using after or afterEach effectively results in the same behaviour.

oh wait, is after an alias for afterEach?

not really after and afterEach are different hooks
after: Runs once after all tests in a describe block have completed
afterEach: Runs after each individual test in a describe block

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that's what is confusing me. In ruby rspec, there's after/after(:each)/after(:all). after is an alias of after(:each) because it's generally a really bad idea to use after(:all) as that implies there's state contamination that you are using.

image

Be very careful with before/after (:all).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@asirvadAbrahamVarghese asirvadAbrahamVarghese Aug 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to afterEach in all cases except this one, which is tied to issue #9512, tagging with TODO for followup.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#9523 is merged so #9512 should be fixed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, switched to afterEach

@asirvadAbrahamVarghese asirvadAbrahamVarghese force-pushed the tenants-form-automation-testing branch 2 times, most recently from be75b2c to 5d4ec73 Compare August 14, 2025 03:29
@asirvadAbrahamVarghese asirvadAbrahamVarghese force-pushed the tenants-form-automation-testing branch 4 times, most recently from f59a514 to 1fe2474 Compare August 14, 2025 07:14

it('Validate cancel button on Add child tenant form', () => {
// Cancel the add operation
cancelForm();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we call cancelForm(); in several other places... I'm not sure it's worth testing on it's own here. Maybe it can be tested in the test above: validateFormElements. In other words, when validating the add child tenant form elements, I'm thinking the cancel button is part of a way to test the form.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moving that into the test above 'Validate Add child tenant form elements' (see)
I avoided placing that inside validateFormElements because it's used in other tests where cancel validation isn’t needed & adding a flag to control it would make it less clean

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now moved along with "Add & delete child tenant" test, as discussed above

@asirvadAbrahamVarghese asirvadAbrahamVarghese force-pushed the tenants-form-automation-testing branch 3 times, most recently from dd4684f to 6f9f4bb Compare August 19, 2025 08:50
// Assert form header is visible
cy.expect_explorer_title(formHeaderFragment);
// Assert name field label is visible
cy.getFormLabelByInputId(nameInputFieldId).should('be.visible');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we care about the getFormLabelByInputId? We only check that the element is in the dom and has that id. We don't check the value elsewhere. If we care, we should check the id has a value or remove it entirely. Thoughts?

Copy link
Contributor Author

@asirvadAbrahamVarghese asirvadAbrahamVarghese Aug 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to check the label text: see

but I am also thinking to use .contains in getFormLabelByInputId as we did with getFormFooterButtonByType
It might make sense to use .contains when a specific text is passed, and .get otherwise, as the label is already targeted using the linked element’s ID (for attribute), which should uniquely identify it.

Cypress.Commands.add(
  'getFormLabelByForAttributeAndText',
  ({ forValue, labelText }) => {
    if (forValue) {
      return labelText
        ? cy.contains(
            `#main-content .bx--form label[for="${forValue}"]`,
            labelText
          )
        : cy.get(`#main-content .bx--form label[for="${forValue}"]`);
    }
    cy.logAndThrowError('forValue is required');
  }
);

Can be done as part of #9598

.should('be.visible')
.and('be.enabled');
// Assert description field label is visible
cy.getFormLabelByInputId(descriptionInputFieldId).should('be.visible');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

Copy link
Contributor Author

@asirvadAbrahamVarghese asirvadAbrahamVarghese Aug 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to check the label text: see

@asirvadAbrahamVarghese asirvadAbrahamVarghese force-pushed the tenants-form-automation-testing branch 2 times, most recently from 67570c4 to 4e9c401 Compare August 29, 2025 09:57
@asirvadAbrahamVarghese asirvadAbrahamVarghese force-pushed the tenants-form-automation-testing branch from 4e9c401 to 9fc6bb4 Compare September 1, 2025 06:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants