From f601e5ace0243ec4848a25ad54465c4287055322 Mon Sep 17 00:00:00 2001 From: "vivi-the-going-merry[bot]" <308115520+vivi-the-going-merry[bot]@users.noreply.github.com> Date: Wed, 23 Sep 2026 11:14:44 -0600 Subject: [PATCH 1/2] Fix removeField's delete assertion to check a real field id li[data-type="${field}"] stringified a Cypress chainable, never matching anything, so the assertion passed unconditionally regardless of whether the field was actually deleted. data-type also isn't unique per field (the original and its duplicate share the same type slug), so swapping in the type string wouldn't have fixed it either - use the field's own data-fid, captured before deletion, instead. Fixes #3430 --- .../e2e/Forms/fieldsInFormBuilder-crud.cy.js | 57 ++++++++++--------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/tests/cypress/e2e/Forms/fieldsInFormBuilder-crud.cy.js b/tests/cypress/e2e/Forms/fieldsInFormBuilder-crud.cy.js index 2485fe8d15..ec681be635 100644 --- a/tests/cypress/e2e/Forms/fieldsInFormBuilder-crud.cy.js +++ b/tests/cypress/e2e/Forms/fieldsInFormBuilder-crud.cy.js @@ -50,36 +50,41 @@ describe( 'Fields in the form builder', () => { }; const removeField = field => { - field.within( () => { - // Same .frm-show-hover opacity gate as the toggle above - reveal it first. - // Same #wpbody-content 1280x0 race as createAndDuplicateField above - // (formidable-forms#3399) - .scrollIntoView() first reliably clears it. - cy.get( '.frm-field-action-icons' ) - .invoke( 'css', 'opacity', 1 ) - .find( '.dropdown .frm-hover-icon .frmsvg' ) - .first() - .scrollIntoView() - .should( 'be.visible' ) - .click(); + // data-type holds the field's type slug (e.g. "text"), shared by the original and its + // duplicate - not unique enough to prove *this* field is gone. data-fid is the field's + // own database id, so capture it before deleting to assert against afterward. + field.invoke( 'attr', 'data-fid' ).then( fid => { + field.within( () => { + // Same .frm-show-hover opacity gate as the toggle above - reveal it first. + // Same #wpbody-content 1280x0 race as createAndDuplicateField above + // (formidable-forms#3399) - .scrollIntoView() first reliably clears it. + cy.get( '.frm-field-action-icons' ) + .invoke( 'css', 'opacity', 1 ) + .find( '.dropdown .frm-hover-icon .frmsvg' ) + .first() + .scrollIntoView() + .should( 'be.visible' ) + .click(); + + // The menu is open via the click above (not hover-gated), so wait for the item to + // be visible instead of forcing through the open transition. + cy.get( '.frm-dropdown-menu .frm_delete_field' ) + .should( 'be.visible' ) + .and( 'contain', 'Delete' ) + .click(); + } ); - // The menu is open via the click above (not hover-gated), so wait for the item to - // be visible instead of forcing through the open transition. - cy.get( '.frm-dropdown-menu .frm_delete_field' ) + // Plain cy.get() by id (an id is unique) rather than cy.get().contains() - the latter + // can resolve to a narrower descendant node than the clickable link itself, which is + // what forced force here. Plain cy.get() on this id works unforced elsewhere in the + // suite. + cy.get( '#frm-confirmed-click' ) .should( 'be.visible' ) - .and( 'contain', 'Delete' ) + .and( 'contain', 'Confirm' ) .click(); - } ); - // Plain cy.get() by id (an id is unique) rather than cy.get().contains() - the latter - // can resolve to a narrower descendant node than the clickable link itself, which is - // what forced force here. Plain cy.get() on this id works unforced elsewhere in the - // suite. - cy.get( '#frm-confirmed-click' ) - .should( 'be.visible' ) - .and( 'contain', 'Confirm' ) - .click(); - - cy.get( `li[data-type="${ field }"]` ).should( 'not.exist' ); + cy.get( `li[data-fid="${ fid }"]` ).should( 'not.exist' ); + } ); }; cy.contains( '#the-list tr', 'Test Form' ).trigger( 'mouseover' ).then( $row => { From 6cb466a9461b0addbcff2f7bc581b43ff3170f31 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, 26 Sep 2026 09:20:22 -0600 Subject: [PATCH 2/2] Fix removeField's within() to scope off the captured element, not a re-derived chainable Franky's own suggested restructuring (move field.within() out of the .then() callback) fixed the reported CI failure but still failed locally on a later field in the same loop - field.within() re-derived from the `field` chainable a second time, after other fields' own removeField() calls had already queued commands in between, doesn't reliably yield this field's own element. Instead, read data-fid and scope every command inside a single field.then($field => ...) callback, using cy.wrap($field) to start a fresh chain rooted at the already-resolved jQuery element rather than re-deriving from `field` at all. Confirmed red against Franky's own suggested diff and green against this one, both via a real local Cypress run (~/Claude/test-sites/formidable/formidable, standalone Lite site, alternate port to avoid a port-3000 collision with another site's own leftover container). --- tests/cypress/e2e/Forms/fieldsInFormBuilder-crud.cy.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/cypress/e2e/Forms/fieldsInFormBuilder-crud.cy.js b/tests/cypress/e2e/Forms/fieldsInFormBuilder-crud.cy.js index ec681be635..6339cdc753 100644 --- a/tests/cypress/e2e/Forms/fieldsInFormBuilder-crud.cy.js +++ b/tests/cypress/e2e/Forms/fieldsInFormBuilder-crud.cy.js @@ -53,8 +53,14 @@ describe( 'Fields in the form builder', () => { // data-type holds the field's type slug (e.g. "text"), shared by the original and its // duplicate - not unique enough to prove *this* field is gone. data-fid is the field's // own database id, so capture it before deleting to assert against afterward. - field.invoke( 'attr', 'data-fid' ).then( fid => { - field.within( () => { + // Read via .then($field => ...) and scope every command to that jQuery element with + // cy.wrap() - re-deriving commands from the stored `field` chainable a second time here + // (after other fields' own removeField() calls have queued commands in between) doesn't + // reliably yield this field's own element. + field.then( $field => { + const fid = $field.attr( 'data-fid' ); + + cy.wrap( $field ).within( () => { // Same .frm-show-hover opacity gate as the toggle above - reveal it first. // Same #wpbody-content 1280x0 race as createAndDuplicateField above // (formidable-forms#3399) - .scrollIntoView() first reliably clears it.