From 65c41857695ccc6f8267367477fbb65e63abb527 Mon Sep 17 00:00:00 2001 From: "vivi-the-going-merry[bot]" <308115520+vivi-the-going-merry[bot]@users.noreply.github.com> Date: Fri, 18 Sep 2026 18:39:05 -0600 Subject: [PATCH 1/3] Fix 2 flaky Cypress e2e specs on fix_e2e_tests_failing deleteEntries.cy.js: the first sidebar field-add click after saving a new form's name can race the builder's own JS mounting into #wpbody-content, past the default 4s command timeout - give it more room. The remaining sidebar clicks land once that settles. searchFunctionality.cy.js: createNewForm()'s builder-close navigation can still be settling when the first search interaction runs right after - same fix, applied to the one call that races it. Not touched by fix_e2e_tests_failing itself, so this was failing independently of that branch's force:true removal. Fixes Strategy11/formidable-forms#3389 --- tests/cypress/e2e/Entries/deleteEntries.cy.js | 6 ++++-- tests/cypress/e2e/Forms/searchFunctionality.cy.js | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/cypress/e2e/Entries/deleteEntries.cy.js b/tests/cypress/e2e/Entries/deleteEntries.cy.js index c3de7144a1..4563d4fb0f 100644 --- a/tests/cypress/e2e/Entries/deleteEntries.cy.js +++ b/tests/cypress/e2e/Entries/deleteEntries.cy.js @@ -14,8 +14,10 @@ describe( 'Entries submitted from a form', () => { cy.get( '#frm-save-form-name-button' ).should( 'contain', 'Save' ).click(); cy.log( `Add some fields` ); - // Plain, always-visible sidebar links - no hover gating involved. - cy.get( 'li[id="text"] a[title="Text"]' ).should( 'be.visible' ).click(); + // Plain, always-visible sidebar links - no hover gating involved. The first one can still + // race the builder's own JS mounting into #wpbody-content right after the save-name + // navigation, longer than the default 4s command timeout - the rest land once that's settled. + cy.get( 'li[id="text"] a[title="Text"]', { timeout: 10000 } ).should( 'be.visible' ).click(); cy.get( 'li[id="name"] a[title="Name"]' ).should( 'be.visible' ).click(); cy.get( 'li[id="checkbox"] a[title="Checkboxes"]' ).should( 'be.visible' ).click(); cy.get( 'li[id="email"] a[title="Email"]' ).should( 'be.visible' ).click(); diff --git a/tests/cypress/e2e/Forms/searchFunctionality.cy.js b/tests/cypress/e2e/Forms/searchFunctionality.cy.js index 7513415129..398b64892c 100644 --- a/tests/cypress/e2e/Forms/searchFunctionality.cy.js +++ b/tests/cypress/e2e/Forms/searchFunctionality.cy.js @@ -9,7 +9,8 @@ describe( 'Search functionality', () => { cy.createNewForm(); cy.log( 'Search the newly created form by using enter' ); - cy.get( '#entry-search-input' ).type( 'Test Form {enter}' ); + // createNewForm()'s builder-close navigation can still be settling when this runs next. + cy.get( '#entry-search-input' ).type( 'Test Form {enter}', { timeout: 10000 } ); cy.get( '.current > .count' ).should( 'contain', '1' ); cy.log( 'Search the newly created form by using the submit button' ); From 602cfce782fa4b5553c603a1c505a9307cbf87c4 Mon Sep 17 00:00:00 2001 From: "vivi-the-going-merry[bot]" <308115520+vivi-the-going-merry[bot]@users.noreply.github.com> Date: Fri, 18 Sep 2026 19:43:30 -0600 Subject: [PATCH 2/3] Fix root cause of 2 flaky Cypress e2e specs, not just symptoms deleteEntries.cy.js: the prior fix bumped only the first sidebar field-add click's timeout, assuming a render-timing race. Verified locally (wp-env + Cypress, 4 clean runs) this isn't timing-based at all - it's deterministic. The scrollable field-type panel (.frm-right-panel) keeps whatever scroll position an earlier click left it at, so a later field link (e.g. Checkboxes, 3rd in the list) can sit permanently outside its own panel's visible scroll area - confirmed via bounding-rect inspection (negative Y, scrolled above the fold), not Cypress's reported #wpbody-content overflow/height (a red herring: that ancestor collapses because a position:fixed descendant takes the real content out of its flow). No timeout, however long, resolves a stale scroll offset. Fix: scrollIntoView() each field-add link before asserting visible. searchFunctionality.cy.js: confirmed this one genuinely is timing - a search submits a real page navigation (not AJAX), and the result-count assertion right after can race the reload past the default 4s timeout. Verified locally (5 clean runs) with the timeout moved onto the .count assertions themselves rather than the .type() call that precedes them. Fixes Strategy11/formidable-forms#3389 --- tests/cypress/e2e/Entries/deleteEntries.cy.js | 18 ++++++++++-------- .../e2e/Forms/searchFunctionality.cy.js | 9 +++++---- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/tests/cypress/e2e/Entries/deleteEntries.cy.js b/tests/cypress/e2e/Entries/deleteEntries.cy.js index 4563d4fb0f..bf61f7150c 100644 --- a/tests/cypress/e2e/Entries/deleteEntries.cy.js +++ b/tests/cypress/e2e/Entries/deleteEntries.cy.js @@ -14,14 +14,16 @@ describe( 'Entries submitted from a form', () => { cy.get( '#frm-save-form-name-button' ).should( 'contain', 'Save' ).click(); cy.log( `Add some fields` ); - // Plain, always-visible sidebar links - no hover gating involved. The first one can still - // race the builder's own JS mounting into #wpbody-content right after the save-name - // navigation, longer than the default 4s command timeout - the rest land once that's settled. - cy.get( 'li[id="text"] a[title="Text"]', { timeout: 10000 } ).should( 'be.visible' ).click(); - cy.get( 'li[id="name"] a[title="Name"]' ).should( 'be.visible' ).click(); - cy.get( 'li[id="checkbox"] a[title="Checkboxes"]' ).should( 'be.visible' ).click(); - cy.get( 'li[id="email"] a[title="Email"]' ).should( 'be.visible' ).click(); - cy.get( 'li[id="phone"] a[title="Phone"]' ).should( 'be.visible' ).click(); + // Plain, always-visible sidebar links - no hover gating involved. Adding a field can leave + // the scrollable field-type panel (.frm-right-panel) scrolled to wherever the previous click + // left it, so a later link in the list can sit outside its own panel's visible scroll area - + // not a render-timing race (a longer timeout never resolves it), so scroll each one into view + // within its own panel before asserting visible. + cy.get( 'li[id="text"] a[title="Text"]' ).scrollIntoView().should( 'be.visible' ).click(); + cy.get( 'li[id="name"] a[title="Name"]' ).scrollIntoView().should( 'be.visible' ).click(); + cy.get( 'li[id="checkbox"] a[title="Checkboxes"]' ).scrollIntoView().should( 'be.visible' ).click(); + cy.get( 'li[id="email"] a[title="Email"]' ).scrollIntoView().should( 'be.visible' ).click(); + cy.get( 'li[id="phone"] a[title="Phone"]' ).scrollIntoView().should( 'be.visible' ).click(); cy.log( 'Update form' ); cy.get( '#frm_submit_side_top' ).should( 'contain', 'Update' ).click(); diff --git a/tests/cypress/e2e/Forms/searchFunctionality.cy.js b/tests/cypress/e2e/Forms/searchFunctionality.cy.js index 398b64892c..955b0898ac 100644 --- a/tests/cypress/e2e/Forms/searchFunctionality.cy.js +++ b/tests/cypress/e2e/Forms/searchFunctionality.cy.js @@ -9,9 +9,10 @@ describe( 'Search functionality', () => { cy.createNewForm(); cy.log( 'Search the newly created form by using enter' ); - // createNewForm()'s builder-close navigation can still be settling when this runs next. + // A search submits a real page navigation, not an AJAX update - the reload can still be + // settling past the default 4s command timeout when the result count is checked right after. cy.get( '#entry-search-input' ).type( 'Test Form {enter}', { timeout: 10000 } ); - cy.get( '.current > .count' ).should( 'contain', '1' ); + cy.get( '.current > .count', { timeout: 10000 } ).should( 'contain', '1' ); cy.log( 'Search the newly created form by using the submit button' ); cy.get( '#entry-search-input' ).type( 'Test Form' ).clear(); @@ -19,13 +20,13 @@ describe( 'Search functionality', () => { cy.get( '#search-submit' ).click(); cy.get( '.published > .current' ).should( 'exist' ); - cy.get( '.current > .count' ).should( 'contain', '1' ); + cy.get( '.current > .count', { timeout: 10000 } ).should( 'contain', '1' ); cy.get( '.displaying-num' ).should( 'contain', '1' ); cy.contains( '#the-list tr', 'Test Form' ).should( 'exist' ); cy.log( 'Search for an invalid form title' ); cy.get( '#entry-search-input' ).clear().type( 'Invalid Test Form {enter}' ); - cy.get( '.current > .count' ).should( 'contain', '0' ); + cy.get( '.current > .count', { timeout: 10000 } ).should( 'contain', '0' ); cy.get( '#entry-search-input' ).clear(); cy.get( '#search-submit' ).click(); From ca23efef1b23504493a8eece99250293c309ddc4 Mon Sep 17 00:00:00 2001 From: "vivi-the-going-merry[bot]" <308115520+vivi-the-going-merry[bot]@users.noreply.github.com> Date: Sat, 19 Sep 2026 04:27:41 -0600 Subject: [PATCH 3/3] Fix identical race on .published > .current assertion Same root cause as the .current > .count fix two lines down: this assertion follows the same #search-submit click/navigation and can time out for the same reason on a slow CI run. --- tests/cypress/e2e/Forms/searchFunctionality.cy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cypress/e2e/Forms/searchFunctionality.cy.js b/tests/cypress/e2e/Forms/searchFunctionality.cy.js index 955b0898ac..284b5f9e1c 100644 --- a/tests/cypress/e2e/Forms/searchFunctionality.cy.js +++ b/tests/cypress/e2e/Forms/searchFunctionality.cy.js @@ -19,7 +19,7 @@ describe( 'Search functionality', () => { cy.get( '#entry-search-input' ).type( 'Test Form' ); cy.get( '#search-submit' ).click(); - cy.get( '.published > .current' ).should( 'exist' ); + cy.get( '.published > .current', { timeout: 10000 } ).should( 'exist' ); cy.get( '.current > .count', { timeout: 10000 } ).should( 'contain', '1' ); cy.get( '.displaying-num' ).should( 'contain', '1' ); cy.contains( '#the-list tr', 'Test Form' ).should( 'exist' );