diff --git a/frontend/controller/actions/group.js b/frontend/controller/actions/group.js index d6bbaba48..fc993a44a 100644 --- a/frontend/controller/actions/group.js +++ b/frontend/controller/actions/group.js @@ -971,6 +971,14 @@ export default (sbp('sbp/selectors/register', { const response = await sendMessage({ ...params, data: { ...data, passPayload } }) if (proposalToSend) { + // NOTE: sometimes 'notifyProposalStateInGeneralChatRoom' function could be called + // after the 'proposalVote' event is finished its processing (published, received, called process/sideEffect) + // it's not a big problem unless the proposal to remove someone from the group is accepted by the current vote. + // it's when the two messages will be created in general chatroom; one is to tells the proposal is approved + // and the other is to tell the member is left general chatroom. + // the order of two functions that will be called means the order of the two messages in general chatroom. + // so the order of messages isn't always same and that could cause the heisenbug below + // https://github.com/okTurtles/group-income/tree/2226-heisenbug-in-group-chatspecjs-more-persistent-one await sbp('gi.actions/group/notifyProposalStateInGeneralChatRoom', { groupID: contractID, proposal: proposalToSend diff --git a/test/cypress/integration/group-chat.spec.js b/test/cypress/integration/group-chat.spec.js index 8215eb65e..246650d0c 100644 --- a/test/cypress/integration/group-chat.spec.js +++ b/test/cypress/integration/group-chat.spec.js @@ -51,26 +51,30 @@ describe('Group Chat Basic Features (Create & Join & Leave & Close)', () => { // considering it sync the chatroom contract from the beginning } else { const message = selfLeave ? `Left ${channelName}` : `Kicked a member from ${channelName}: ${leaver}` + const messageSelectors = { + last: 'div.c-message:last-child', + secondLast: 'div.c-message:nth-last-child(2)' + } + const assertKickerAndMessageContent = (msgSelector) => { + cy.get(`${msgSelector} .c-who > span:first-child`).should('contain', kicker) + cy.get(`${msgSelector} .c-notification`).should('contain', message) + } - let isLastElement = true if (byProposal) { // NOTE: when the member is kicked from the from by proposal // two messages will be created in general chatroom; INTERACTIVE, and NOTIFICATION // INTERACTIVE message should be created before the NOTIFICATION message - // but sometimes (only in Cypress) NOTIFICATION message could be created earlier - // this block is to handle that heisenbug - cy.wait(1000) // eslint-disable-line cypress/no-unnecessary-waiting - cy.get('div.c-message:last-child').invoke('attr', 'class').then(classNames => { - isLastElement = classNames.includes('is-type-notification') + // but sometimes (mostly in Cypress) NOTIFICATION message could be created earlier + // and the order of two messages could be changed and it could cause the heisenbug. + // the below block is to handle that heisenbug + cy.get(messageSelectors.last).invoke('attr', 'class').then(classNames => { + const isLastMsgTypeNotification = classNames.includes('is-type-notification') + assertKickerAndMessageContent( + isLastMsgTypeNotification ? messageSelectors.last : messageSelectors.secondLast + ) }) - } - - if (isLastElement) { - cy.get('div.c-message:last-child .c-who > span:first-child').should('contain', kicker) - cy.get('div.c-message:last-child .c-notification').should('contain', message) } else { - cy.get('div.c-message:nth-last-child(2) .c-who > span:first-child').should('contain', kicker) - cy.get('div.c-message:nth-last-child(2) .c-notification').should('contain', message) + assertKickerAndMessageContent(messageSelectors.last) } } } @@ -411,6 +415,10 @@ describe('Group Chat Basic Features (Create & Join & Leave & Close)', () => { cy.getByDT('groupMembers').find('ul>li').should('have.length', 2) // user1 & user2 + // NOTE: this check is to wait until 2 INTERACTIVE mesages are created + // one for creating proposal and another is for proposal approval + cy.getByDT('groupChatLink').get('.c-badge.is-compact[aria-label="2 new notifications"]').contains('2') + cy.giRedirectToGroupChat() cy.giSwitchChannel(CHATROOM_GENERAL_NAME)