From 27612aaf2c881199173f35ab1f721078a2b2f7c2 Mon Sep 17 00:00:00 2001 From: Joe Rafaniello Date: Wed, 19 Nov 2025 13:33:09 -0500 Subject: [PATCH] Fix bug where a GET triggered by a test, is processed after the test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sporadically, I was noticing the GET below happening during the teardown of the test: "/api/tenants?filter[]=name=&expand=resources" It turns out we have a form validation for the name field that gets a list of tenant names on form load to prevent the user from providing a duplicate name. For the edit tenant form, we ALSO have an API tenant data request that occurs BEFORE the tenant form loads. Because of this, we need to wait on the single form validation API request for the add form and for the edit form, we need to wait for the load API request first, then, the same validation API request. This should fix the following issue that was happening sporadically locally and in CI: ``` Validate Child Tenant operations: Add, Edit, Add Project, Manage Quotas Validate Add child tenant function ✖(Attempt 1 of 10) Validate Add child tenant form elements ✖(Attempt 2 of 10) Validate Add child tenant form elements ✖(Attempt 3 of 10) Validate Add child tenant form elements ✖(Attempt 4 of 10) Validate Add child tenant form elements ✖(Attempt 5 of 10) Validate Add child tenant form elements ✖(Attempt 6 of 10) Validate Add child tenant form elements ✖(Attempt 7 of 10) Validate Add child tenant form elements ✖(Attempt 8 of 10) Validate Add child tenant form elements ✖(Attempt 9 of 10) Validate Add child tenant form elements ✖(Attempt 10 of 10) "before each" hook for "Validate Add child tenant form elements" ✖ "before each" hook for "Validate Add child tenant form elements" (30358ms) 6 passing (4m) 1 failing 1) Automate Tenant form operations: Settings > Application Settings > Access Control > Tenants Validate Child Tenant operations: Add, Edit, Add Project, Manage Quotas Validate Add child tenant function "before each" hook for "Validate Add child tenant form elements": CypressError: `cy.visit()` failed trying to load: http://localhost:3000/ We attempted to make an http request to this URL but the request failed without a response. We received this error at the network level: > Error: ESOCKETTIMEDOUT ``` --- .../Application-Settings/tenant.cy.js | 41 +++++++++++++++---- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/cypress/e2e/ui/Settings/Application-Settings/tenant.cy.js b/cypress/e2e/ui/Settings/Application-Settings/tenant.cy.js index cd2727b0b25..66cc9f329a5 100644 --- a/cypress/e2e/ui/Settings/Application-Settings/tenant.cy.js +++ b/cypress/e2e/ui/Settings/Application-Settings/tenant.cy.js @@ -68,6 +68,31 @@ function confirmUiNavigation(callback) { }); } +function openTenantFormAndWaitForValidation(configOption) { + cy.interceptApi({ + method: 'GET', + alias: 'tenantValidationApi', + urlPattern: /\/api\/tenants\?filter\[\]=name=.*&expand=resources/, + triggerFn: () => cy.toolbar(CONFIG_TOOLBAR_BUTTON, configOption), + }); +} + +function openEditTenantFormAndWaitForLoad(configOption) { + // Tenant edit form triggers two API calls in sequence: + // 1. Load existing tenant data (happens first in useEffect, in ops-tenant-form.jsx) + // 2. Form validation API (happens after load completes and form renders with validateOnMount: true) + // The form doesn't render until isLoading=false, so validation always happens after the form loads. + cy.intercept('GET', /\/api\/tenants\/\d+\?expand=resources&attributes=/).as('tenantLoadApi'); + cy.intercept('GET', /\/api\/tenants\?filter\[\]=name=.*&expand=resources/).as('tenantValidationApi'); + + cy.toolbar(CONFIG_TOOLBAR_BUTTON, configOption); + + // Wait for both API calls to complete in order + // Load API must complete first (component logic ensures this) + cy.wait('@tenantLoadApi'); + cy.wait('@tenantValidationApi'); +} + function cancelFormWithOptionalFlashCheck(assertFlashMessage = true) { cy.getFormButtonByTypeWithText({ buttonText: CANCEL_BUTTON_TEXT, @@ -162,7 +187,7 @@ function validateFormElements(isEditForm = true) { } function createAndSelectChildTenant() { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_CHILD_TENANT_CONFIG_OPTION); + openTenantFormAndWaitForValidation(ADD_CHILD_TENANT_CONFIG_OPTION); updateNameAndDescription( INITIAL_CHILD_TENANT_NAME, INITIAL_CHILD_TENANT_DESCRIPTION @@ -186,7 +211,7 @@ function resetParentTenantForm() { // Check if the text matches the edited parent tenant name, if yes reset if (text === EDITED_TENANT_NAME_VALUE) { cy.wrap(item).click(); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_TENANT_CONFIG_OPTION); + openEditTenantFormAndWaitForLoad(EDIT_TENANT_CONFIG_OPTION); updateNameAndDescription( INITIAL_PARENT_TENANT_NAME, INITIAL_PARENT_TENANT_DESCRIPTION @@ -229,7 +254,7 @@ function deleteAccordionItems(accordionsToDelete) { } function addProjectToTenant() { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_PROJECT_CONFIG_OPTION); + openTenantFormAndWaitForValidation(ADD_PROJECT_CONFIG_OPTION); updateNameAndDescription(PROJECT_NAME_VALUE, EDITED_DESCRIPTION_VALUE); saveFormWithOptionalFlashCheck({ button: ADD_BUTTON_TEXT, @@ -275,7 +300,7 @@ describe('Automate Tenant form operations: Settings > Application Settings > Acc describe('Validate Parent Tenant operations: Edit, Add Project, Manage Quotas', () => { describe('Validate Edit parent tenant', () => { beforeEach(() => { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_TENANT_CONFIG_OPTION); + openEditTenantFormAndWaitForLoad(EDIT_TENANT_CONFIG_OPTION); }); afterEach(() => { @@ -347,7 +372,7 @@ describe('Automate Tenant form operations: Settings > Application Settings > Acc describe('Validate Child Tenant operations: Add, Edit, Add Project, Manage Quotas', () => { describe('Validate Add child tenant function', () => { beforeEach(() => { - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_CHILD_TENANT_CONFIG_OPTION); + openTenantFormAndWaitForValidation(ADD_CHILD_TENANT_CONFIG_OPTION); }); afterEach(() => { @@ -364,7 +389,7 @@ describe('Automate Tenant form operations: Settings > Application Settings > Acc INITIAL_CHILD_TENANT_DESCRIPTION ); cancelFormWithOptionalFlashCheck(); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_CHILD_TENANT_CONFIG_OPTION); + openTenantFormAndWaitForValidation(ADD_CHILD_TENANT_CONFIG_OPTION); updateNameAndDescription( INITIAL_CHILD_TENANT_NAME, INITIAL_CHILD_TENANT_DESCRIPTION @@ -387,7 +412,7 @@ describe('Automate Tenant form operations: Settings > Application Settings > Acc button: ADD_BUTTON_TEXT, flashMessageSnippet: FLASH_MESSAGE_ADDED, }); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, ADD_CHILD_TENANT_CONFIG_OPTION); + openTenantFormAndWaitForValidation(ADD_CHILD_TENANT_CONFIG_OPTION); cy.getFormInputFieldByIdAndType({ inputId: 'name' }).type( INITIAL_CHILD_TENANT_NAME ); @@ -401,7 +426,7 @@ describe('Automate Tenant form operations: Settings > Application Settings > Acc describe('Validate Edit child tenant', () => { beforeEach(() => { createAndSelectChildTenant(); - cy.toolbar(CONFIG_TOOLBAR_BUTTON, EDIT_TENANT_CONFIG_OPTION); + openEditTenantFormAndWaitForLoad(EDIT_TENANT_CONFIG_OPTION); }); afterEach(() => {