diff --git a/ui.tests/test-module/libs/support/commands.js b/ui.tests/test-module/libs/support/commands.js index e8e49c42c3..2c21d80d4e 100644 --- a/ui.tests/test-module/libs/support/commands.js +++ b/ui.tests/test-module/libs/support/commands.js @@ -317,6 +317,21 @@ Cypress.Commands.add("invokeEditableAction", (actionSelector) => { cy.get(actionSelector).should('be.visible').click({force: true}); }); +// cypress command to submit a component's configure dialog and wait for the editor to settle. +// A config-dialog submit fires an asynchronous editable re-render that repositions the overlays and +// hides the shared #EditableToolbar. Any openEditableToolbar issued before that re-render settles +// races the teardown: recurse opens the toolbar, the late reposition hides it, and the trailing +// should('be.visible') (never re-clicks) times out with "#EditableToolbar has display: none". +// Register the same editable-update + overlay-reposition listeners deleteComponentByPath relies on +// BEFORE clicking submit, then block until both fire so callers can safely reopen the toolbar next. +Cypress.Commands.add("submitConfigureDialog", (submitSelector = ".cq-dialog-submit") => { + cy.initializeEventHandlerOnChannel(siteConstants.EVENT_NAME_EDITABLES_UPDATED).as("isConfigureEditableUpdated"); + cy.initializeEventHandlerOnChannel(siteConstants.EVENT_NAME_OVERLAYS_REPOSITIONED).as("isConfigureOverlaysRepositioned"); + cy.get(submitSelector).click({force: true}); + cy.get("@isConfigureEditableUpdated").its('done').should('equal', true); // wait until re-render done + cy.get("@isConfigureOverlaysRepositioned").its('done').should('equal', true); // wait until overlays settled +}); + // cypress command to initialize event handler on channel Cypress.Commands.add("initializeEventHandlerOnChannel", (eventName) => { let isEventComplete = {done: false}; diff --git a/ui.tests/test-module/libs/support/index.js b/ui.tests/test-module/libs/support/index.js index 128fc247eb..d6d8ae784e 100644 --- a/ui.tests/test-module/libs/support/index.js +++ b/ui.tests/test-module/libs/support/index.js @@ -125,6 +125,15 @@ Cypress.on('uncaught:exception', (err, runnable) => { return false; } + // Intermittent CoralUI3 component-bootstrap error while the editor chrome/template structure page + // upgrades its Coral custom elements. A property getter returns the boolean `true` where Coral + // expects an element/object and then tries to attach `_namespace` to it, throwing. It is racy + // (depends on Coral upgrade timing), recovers on the next tick, and has no functional impact on + // the form under test, so it must not fail the test. + if(err.message.includes("Cannot create property '_namespace'")) { + return false; + } + // we still want to ensure there are no other unexpected // errors, so we let them fail the test return true; diff --git a/ui.tests/test-module/specs/actions/viewQualifiedName/viewQualifiedName.authoring.cy.js b/ui.tests/test-module/specs/actions/viewQualifiedName/viewQualifiedName.authoring.cy.js index df55aa6c90..f06eeac734 100644 --- a/ui.tests/test-module/specs/actions/viewQualifiedName/viewQualifiedName.authoring.cy.js +++ b/ui.tests/test-module/specs/actions/viewQualifiedName/viewQualifiedName.authoring.cy.js @@ -108,7 +108,9 @@ describe("View Qualified Name Tests", () => { cy.invokeEditableAction("[data-action='CONFIGURE']"); cy.get(".cq-dialog").should("be.visible"); cy.get("[name='./name']").click().clear().type(name); - cy.get(submitBtnSelector).click({force: true}); + // wait for the editor to settle after submit so the next openEditableToolbar doesn't race + // the re-render that hides #EditableToolbar (see submitConfigureDialog in commands.js) + cy.submitConfigureDialog(submitBtnSelector); } const testQualifiedName = (componentEditPathSelector, componentDrop, isSites) => { @@ -221,7 +223,9 @@ describe("View Qualified Name Tests", () => { cy.invokeEditableAction("[data-action='CONFIGURE']"); cy.get(".cq-dialog").should("be.visible"); cy.get("[name='./name']").click().clear().type(name); - cy.get(submitBtnSelector).click({force: true}); + // wait for the editor to settle after submit so the next openEditableToolbar doesn't + // race the re-render that hides #EditableToolbar (see submitConfigureDialog in commands.js) + cy.submitConfigureDialog(submitBtnSelector); cy.openEditableToolbar(sitesSelectors.overlays.overlay.component + accordionEditPathSelector); cy.invokeEditableAction("[data-action='qualifiedName']");