From c8afc0e059ad6a14902939db5140af41f8901516 Mon Sep 17 00:00:00 2001 From: Roland Date: Mon, 3 Aug 2026 19:17:35 -0600 Subject: [PATCH] test: stop the search-modal test depending on an unrelated error toast The other half of CI's cypress-e2e failure: `clicking search icon opens modal` failed with `expected '' to be 'visible'`, covered by a danger toast. Toasts paint above modals on purpose -- z-index 400 against the modal stack's 200 -- so an error raised while a modal is open stays visible. The search modal is tall, so it sits near the top of the window, and a top-right toast covers the right-hand 192px of its 365px input. Cypress occlusion-checks a `position: fixed` element, so the assertion failed. Measured at both scales, because the question was whether the interface scale caused it: 130px of a 330px input before, 192px of 365px after. The overlap is PRE-EXISTING; the scale widened it from 39% of the input to 53%, which is what pushed CI over the line. Roland's call was to accept the overlap -- an error toast belongs on top -- and fix the test. It passed locally and failed in CI because CI serves the React app with no API behind it. The endpoints this spec leaves unmocked are `/api/tag`, `/api/events/feed`, `/api/files/search` and `/api/files/worker_status` -- note that the spec's existing mocks say `/api/tags` and `/api/events`, neither of which the app calls -- so they fail and api.js raises "Unexpected server response". The toast container is removed before the assertion rather than clicked away, because a click races the next failing call. A blanket `/api/**` 200 stub was tried first and does not work: a 200 with the wrong shape fails the same way, which is what "Unexpected server response" means. Verified by reproducing CI's condition locally (`forceNetworkError` on every unmocked endpoint): 12 passing with the removal, 11 passing and 1 failing without it. All 50 e2e specs pass under normal conditions. --- app/cypress/e2e/keyboard-shortcuts.cy.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/cypress/e2e/keyboard-shortcuts.cy.js b/app/cypress/e2e/keyboard-shortcuts.cy.js index 00d4a071..df7f8df6 100644 --- a/app/cypress/e2e/keyboard-shortcuts.cy.js +++ b/app/cypress/e2e/keyboard-shortcuts.cy.js @@ -54,6 +54,27 @@ describe('Keyboard Shortcuts', () => { // Search modal should open cy.get('[role="dialog"]').should('be.visible'); + + /* + * Take down any toast before the assertion below, which is occlusion-sensitive. + * + * Toasts paint above modals on purpose -- z-index 400 against the modal stack's + * 200 -- so that an error raised while a modal is open stays visible. The search + * modal is tall, so it sits near the top of the window, and a top-right toast + * covers the right-hand 192px of its 365px input. Cypress occlusion-checks a + * `position: fixed` element, so `should('be.visible')` on that input fails. + * + * That is not this spec's subject. It passed locally and failed in CI, where the + * React app is served with no API behind it: `/api/tag`, `/api/events/feed`, + * `/api/files/search` and `/api/files/worker_status` are not mocked here, they + * fail, and api.js raises "Unexpected server response". The overlap itself is an + * accepted trade-off -- see the toast/modal note in ui.css -- so the environment is + * made quiet rather than the assertion weakened. + * + * Removed rather than dismissed by clicking: a click races the next failing call. + */ + cy.get('body').then(($body) => $body.find('.mantine-Notifications-root').remove()); + cy.get('[role="dialog"] input').should('be.visible'); });