E2E/Cypress: fix flaky emoji picker reaction helper (#38225)

* E2E/Cypress: re-hover until the emoji picker preview settles

clickEmojiInEmojiPicker hovered an emoji once and then waited on the picker
preview to name it. Loading recent or custom emojis re-renders the picker and
resets its cursor to the first emoji, so a hover that landed just before that
update was discarded and the retrying assertion could never recover.

reactions_spec.js hit this in CI on MM-T2192, which then took the two tests
after it down with it: the test failed before its own uiCloseRHS(), and the
RHS it left open covers the center channel the rest of the file drives.

Retry the hover alongside the assertion, and close the RHS before each test in
reactions_spec.js so a single failure no longer cascades.

Co-authored-by: Cursor <cursoragent@cursor.com>

* E2E/Cypress: hover before waiting on emoji picker preview

clickEmojiInEmojiPicker asserted emoji_picker_preview exists before hovering,
but that testid is only rendered after an emoji is selected. MM-T2186 searches
first, so the helper timed out. Hover each waitUntil retry and use Cypress.$ so
a missing node is falsy instead of findAllByTestId throwing out of the loop.

Co-authored-by: mattermost-code <matty-code@mattermost.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: mattermost-code <matty-code@mattermost.com>
This commit is contained in:
sabril
2026-09-03 10:03:43 +08:00
committed by GitHub
co-authored by mattermost-code Cursor
parent 9939a55ac2
commit d81b68faa5
2 changed files with 24 additions and 4 deletions
@@ -20,6 +20,13 @@ describe('Messaging', () => {
});
});
// These tests share a page (testIsolation is off) and each one assumes the RHS is closed. A test
// that fails before its own uiCloseRHS() would otherwise leave it open over the center channel
// and take the rest of the file down with it, including its own retry.
beforeEach(() => {
cy.uiCloseRHS();
});
it('MM-T2189 Emoji reaction - type +:+1:', () => {
// # Post a message
cy.postMessage('Hello');
+17 -4
View File
@@ -562,11 +562,24 @@ Cypress.Commands.add('checkRunLDAPSync', checkRunLDAPSync);
function clickEmojiInEmojiPicker(emojiName: string) {
cy.get('#emojiPicker').should('exist').and('be.visible').within(() => {
// # Mouse over the emoji to get it selected
cy.findAllByTestId(emojiName).eq(0).trigger('mouseover', {force: true});
// Re-hover each retry: recent/custom emoji loads re-render the picker and
// reset the cursor, and search results omit emoji_picker_preview until an
// emoji is hovered. Cypress.$ so a missing node returns false for waitUntil.
cy.waitUntil(() => {
const $emoji = Cypress.$('#emojiPicker').find(`[data-testid="${emojiName}"]`);
if ($emoji.length === 0) {
return false;
}
// * Verify that preview shows the emoji selected
cy.findAllByTestId('emoji_picker_preview').eq(0).should('exist').and('be.visible').contains(emojiName, {matchCase: false});
return cy.wrap($emoji.eq(0)).trigger('mouseover', {force: true}).then(() => {
const previewText = Cypress.$('#emojiPicker').find('[data-testid="emoji_picker_preview"]').eq(0).text();
return previewText.toLowerCase().includes(emojiName.toLowerCase());
});
}, {
timeout: TIMEOUTS.TEN_SEC,
interval: TIMEOUTS.HALF_SEC,
errorMsg: `Emoji picker preview never showed "${emojiName}"`,
});
// # Click on the emoji
cy.findAllByTestId(emojiName).eq(0).click({force: true});