Skip to content

Commit

Permalink
Fix Cypress failures (#2063)
Browse files Browse the repository at this point in the history
* fix: error to logout before waiting all events queue

* fix: tiny errors

* fix: cypress error related two newly added messages

* chore: updated isInCypress computed prop and Travis retry

* chore: remove sbp import

* chore: tiny update and Travis retry

* chore: reverted recent changes

* fix: tiny error to import variable

* feat: updated test scenario for testing messages

* chore: tiny update and Travis retry

* chore: removed cypressMixin and Travis retry

* chore: tiny updates and Travis retry
  • Loading branch information
Silver-IT authored Jun 14, 2024
1 parent 4dff8a6 commit 80c3ffd
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 251 deletions.
4 changes: 4 additions & 0 deletions frontend/controller/actions/identity.js
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,10 @@ export default (sbp('sbp/selectors/register', {
// TODO: We might not need this second await and 1-3 could be fine (i.e.,
// we could avoid waiting on these 2nd layer of actions)
await sbp('okTurtles.eventQueue/queueEvent', 'encrypted-action', () => {})

// NOTE: wait for all the pending UNREAD_MESSAGES_QUEUE invocations to be finished
await sbp('okTurtles.eventQueue/queueEvent', UNREAD_MESSAGES_QUEUE, () => {})

// See comment below for 'gi.db/settings/delete'
await sbp('state/vuex/save')

Expand Down
12 changes: 6 additions & 6 deletions frontend/views/containers/chatroom/ChatMain.vue
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,7 @@ import ViewArea from './ViewArea.vue'
import Emoticons from './Emoticons.vue'
import TouchLinkHelper from './TouchLinkHelper.vue'
import DragActiveOverlay from './file-attachment/DragActiveOverlay.vue'
import {
MESSAGE_TYPES,
MESSAGE_VARIANTS,
CHATROOM_ACTIONS_PER_PAGE
} from '@model/contracts/shared/constants.js'
import { MESSAGE_TYPES, MESSAGE_VARIANTS, CHATROOM_ACTIONS_PER_PAGE } from '@model/contracts/shared/constants.js'
import { CHATROOM_EVENTS } from '@utils/events.js'
import { findMessageIdx, createMessage } from '@model/contracts/shared/functions.js'
import { proximityDate, MINS_MILLIS } from '@model/contracts/shared/time.js'
Expand Down Expand Up @@ -844,6 +840,10 @@ export default ({
updateReadUntilMessageHash ({ messageHash, createdHeight }) {
const chatRoomID = this.renderingChatRoomId
if (chatRoomID && this.isJoinedChatRoom(chatRoomID)) {
if (this.currentChatRoomReadUntil?.createdHeight >= createdHeight) {
// NOTE: skip adding useless invocations in UNREAD_MESSAGES_QUEUE queue
return
}
sbp('gi.actions/identity/setChatRoomReadUntil', {
contractID: chatRoomID, messageHash, createdHeight
})
Expand Down Expand Up @@ -957,7 +957,7 @@ export default ({
const fromOurselves = this.isMsgSender(this.messages[this.messages.length - 1].from)
if (!fromOurselves && isScrollable) {
this.updateScroll()
} else if (!isScrollable && this.messages.length) {
} else {
const msg = this.messages[this.messages.length - 1]
this.updateReadUntilMessageHash({
messageHash: msg.hash,
Expand Down
216 changes: 147 additions & 69 deletions test/cypress/integration/group-chat-message.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ function makeMentionFromUsername (username) {
}

const groupName = 'Dreamers'
const additionalChannelName = 'bulgaria-hackathon'
const userId = performance.now().toFixed(20).replace('.', '')
const user1 = `user1${userId}`
const user2 = `user2${userId}`
const user3 = `user3${userId}`
let invitationLinkAnyone
let me

describe('Send/edit/remove messages & add/remove emoticons inside group chat', () => {
describe('Send/edit/remove/reply messages & add/remove reactions inside group chat', () => {
function switchUser (username) {
cy.giSwitchUser(username)
me = username
Expand Down Expand Up @@ -111,26 +111,70 @@ describe('Send/edit/remove messages & add/remove emoticons inside group chat', (
})
}

it(`user1 creats '${groupName}' group and joins "${CHATROOM_GENERAL_NAME}" channel by default`, () => {
function switchChannel (channelName) {
cy.getByDT('channelsList').within(() => {
cy.get('ul > li').each(($el, index, $list) => {
if ($el.text() === channelName) {
cy.wrap($el).click()
return false
}
})
})
cy.getByDT('channelName').should('contain', channelName)

cy.giWaitUntilMessagesLoaded()
}

function replyToMessage (nth, message) {
cy.getByDT('conversationWrapper').find(`.c-message:nth-child(${nth})`).within(() => {
cy.get('.c-menu>.c-actions')
.invoke('attr', 'style', 'display: flex')
.invoke('show')
.scrollIntoView()
.should('be.visible')
cy.get('.c-menu>.c-actions button[aria-label="Reply"]').click({ force: true })
cy.get('.c-menu>.c-actions')
.should('be.visible')
.invoke('hide')
.should('be.hidden')
})
cy.get('.c-tooltip.is-active').invoke('hide')

cy.getByDT('messageInputWrapper').within(() => {
cy.get('textarea').should('exist')
cy.get('.c-replying-wrapper').should('exist')
})

sendMessage(message)
}

it(`user1 creates '${groupName}' group and sends/edits messages in "${CHATROOM_GENERAL_NAME}"`, () => {
cy.visit('/')
cy.giSignup(user1, { bypassUI: true })
me = user1

cy.giCreateGroup(groupName, { bypassUI: true })
cy.giGetInvitationAnyone().then(url => {
invitationLinkAnyone = url
})

cy.giRedirectToGroupChat()
cy.getByDT('channelName').should('contain', CHATROOM_GENERAL_NAME)
cy.getByDT('channelsList').within(() => {
cy.get('ul').children().should('have.length', 1)
})
cy.giCheckIfJoinedChatroom(CHATROOM_GENERAL_NAME, me)

sendMessage(`Welcome to the ${groupName}!`)
sendMessage('We are going to make the world better!')
editMessage(4, 'We are helping each other to make the world better!')

cy.getByDT('dashboard').click()
cy.giGetInvitationAnyone().then(url => {
invitationLinkAnyone = url
})

cy.giLogout()
})

it(`user2 joins ${groupName} group and sends greetings, asks to have meeting`, () => {
it(`user2 joins ${groupName} group and sends/deletes/edits messages in "${CHATROOM_GENERAL_NAME}"`, () => {
cy.giAcceptGroupInvite(invitationLinkAnyone, {
username: user2,
existingMemberUsername: user1,
Expand All @@ -141,98 +185,63 @@ describe('Send/edit/remove messages & add/remove emoticons inside group chat', (
me = user2

cy.giRedirectToGroupChat()
sendMessage(`Hello ${user1}. How are you? Thanks for inviting me to this awesome group.`)
sendMessage('Can we have a meeting this morning?')
sendMessage('Oh, yes. I have joined the group now.')
deleteMessage(6, 4)
sendMessage('Anyone here?')
editMessage(6, 'Hello everyone. Thanks for inviting me to this group.')
})

it('user1 sends greetings and edits', () => {
switchUser(user1)
cy.giRedirectToGroupChat()

sendMessage('Hi')

editMessage(7, `Hi ${user2}. I am fine thanks.`)
})

it('user2 edits and deletes message', () => {
switchUser(user2)
cy.giRedirectToGroupChat()

editMessage(5, 'Can we have a meeting this evening?')

deleteMessage(4, 4)
})

it('user1 sees the edited message but he is not able to see the deleted message', () => {
switchUser(user1)
cy.giRedirectToGroupChat()

it('user2 sees totally 5 messages', () => {
cy.getByDT('conversationWrapper').within(() => {
cy.get('.c-message').should('have.length', 4)
cy.get('.c-message').should('have.length', 5)
})

checkMessageBySender(0, user1, `Joined ${CHATROOM_GENERAL_NAME}`)
checkMessageBySender(1, user2, `Joined ${CHATROOM_GENERAL_NAME}`)
checkMessageBySender(2, user2, 'Can we have a meeting this evening?')
checkMessageBySender(3, user1, `Hi ${user2}. I am fine thanks.`)
checkMessageBySender(1, user1, `Welcome to the ${groupName}!`)
checkMessageBySender(2, user1, 'We are helping each other to make the world better!')
checkMessageBySender(3, user2, `Joined ${CHATROOM_GENERAL_NAME}`)
checkMessageBySender(4, user2, 'Hello everyone. Thanks for inviting me to this group.')
})

it('user1 adds 4 emojis and removes 1 emoji', () => {
it('user2 mentions user1 and adds/removes reactions to the message', () => {
sendMessage(`Hi ${makeMentionFromUsername(user1).me}. When is the best time for you to help me with learning more about this group?`)

sendEmoticon(4, '+1', 1)
sendEmoticon(4, 'joy', 2)
sendEmoticon(4, 'grinning', 3)

sendEmoticon(5, 'joy', 1)
sendEmoticon(7, 'joy', 1)

deleteEmotion(4, 2, 2)
})

it('user2 sees the emojis user1 created and adds his emoji', () => {
switchUser(user2)
it('user1 sees the mentions and reactions which user2 created and adds his reaction', () => {
switchUser(user1)
cy.getByDT('groupChatLink').get('.c-badge.is-compact[aria-label="1 new notifications"]').contains('1')
cy.giRedirectToGroupChat()
sendMessage(`Hi ${makeMentionFromUsername(user2).me}. Anytime!`)
sendMessage(`Hi ${makeMentionFromUsername(user2).all}. I am always be with you. Message me anytime.`)
cy.get('[data-test="groupChatLink"] .c-badge.is-compact').should('not.exist')

cy.getByDT('conversationWrapper').within(() => {
cy.get('.c-message:nth-child(4) .c-emoticons-list>.c-emoticon-wrapper').should('have.length', 3)
cy.get('.c-message:nth-child(5) .c-emoticons-list>.c-emoticon-wrapper').should('have.length', 2)
cy.get('.c-message:nth-child(8) .c-emoticons-list>.c-emoticon-wrapper').should('have.length', 2)
})

sendEmoticon(5, '+1', 2)
sendEmoticon(8, '+1', 2)

cy.getByDT('conversationWrapper').within(() => {
cy.get('.c-message:nth-child(5) .c-emoticons-list>.c-emoticon-wrapper').should('have.length', 3)
cy.get('.c-message:nth-child(5) .c-emoticons-list>.c-emoticon-wrapper.is-user-emoticon').should('have.length', 1)
})
cy.giLogout()
})

it(`user3 joins ${groupName} group and mentions user1 and all`, () => {
cy.giAcceptGroupInvite(invitationLinkAnyone, {
username: user3,
existingMemberUsername: user1,
groupName: groupName,
shouldLogoutAfter: false,
bypassUI: true
cy.get('.c-message:nth-child(8) .c-emoticons-list>.c-emoticon-wrapper').should('have.length', 3)
cy.get('.c-message:nth-child(8) .c-emoticons-list>.c-emoticon-wrapper.is-user-emoticon').should('have.length', 1)
})
me = user3
cy.giRedirectToGroupChat()

sendMessage(`Hi ${makeMentionFromUsername(user1).all}. Hope you are doing well.`)
sendMessage(`I am a friend of ${makeMentionFromUsername(user1).me}. Let's work together.`)
})

it('user2 and user1 check mentions for themselves', () => {
it('user2 checks two mentions and sends/deletes attachments', () => {
switchUser(user2)
cy.getByDT('groupChatLink').get('.c-badge.is-compact[aria-label="1 new notifications"]').contains('1')
cy.giRedirectToGroupChat()
cy.get('[data-test="groupChatLink"] .c-badge.is-compact').should('not.exist')

switchUser(user1)
cy.getByDT('groupChatLink').get('.c-badge.is-compact[aria-label="2 new notifications"]').contains('2')
cy.giRedirectToGroupChat()
cy.get('[data-test="groupChatLink"] .c-badge.is-compact').should('not.exist')
})

it('user1 sends two messages with attachments, and deletes attachments', () => {
const fileNames = [
['1.png', '2.png', '3.png'], // Prefix Path: cypress/fixtures/
['imageTest.png', 'test.json']
Expand All @@ -244,7 +253,7 @@ describe('Send/edit/remove messages & add/remove emoticons inside group chat', (
cy.getByDT('attachments').attachFile(fileNames[1])
sendMessage('Sending two files; one is image, and the other is JSON file.')

cy.getByDT('conversationWrapper').find('.c-message:nth-child(10)').within(() => {
cy.getByDT('conversationWrapper').find('.c-message:nth-child(11)').within(() => {
cy.get('.c-attachment-container').find('.c-attachment-preview:nth-child(2)').within(() => {
cy.get('.c-attachment-actions-wrapper').invoke('attr', 'style', 'display: flex').invoke('show')
cy.get('.c-attachment-actions span[aria-label="Delete"]').click()
Expand All @@ -257,9 +266,78 @@ describe('Send/edit/remove messages & add/remove emoticons inside group chat', (
cy.getByDT('submitPrompt').click()
})

cy.getByDT('conversationWrapper').find('.c-message:nth-child(10)').within(() => {
cy.getByDT('conversationWrapper').find('.c-message:nth-child(11)').within(() => {
cy.get('.c-attachment-container').find('.c-attachment-preview').should('have.length', 2)
})
})

it('user2 sends 20 messages and replies to a message too', () => {
for (let i = 1; i <= 20; i++) {
sendMessage(`Text-${i}`)
}

replyToMessage(4, 'Awesome!') // `Hi ${makeMentionFromUsername(user2).me}. Anytime!`

cy.getByDT('conversationWrapper').within(() => {
cy.get('.c-message').last().find('.c-who > span:first-child').should('contain', user2)
cy.get('.c-message').last().find('.c-text').should('contain', 'Awesome!')
cy.get('.c-message').last().should('be.visible').within(() => {
cy.get('.c-replying').should('exist').should('be.visible').click()
})

// HACK: scrollIntoView() should not be there
// But cy.get('.c-replying').click() doesn't scroll to the target message
// Because of this can not move forward to the next stages, so just used HACK
cy.get('.c-message:nth-child(4)')
.should('contain', 'We are helping each other to make the world better!')
.scrollIntoView()
.should('be.visible')
cy.get('.c-replying').should('not.be.visible')
})
})

it('user2 creates a new channel and checks how the scroll position is saved for each channel', () => {
cy.giAddNewChatroom({
name: additionalChannelName,
isPrivate: false,
bypassUI: true
})
cy.giCheckIfJoinedChatroom(additionalChannelName, me)

switchChannel(CHATROOM_GENERAL_NAME)

cy.getByDT('conversationWrapper').within(() => {
cy.contains('We are helping each other to make the world better!').should('be.visible')
})

cy.getByDT('messageInputWrapper').within(() => {
cy.get('.c-jump-to-latest').should('exist').click()
})

cy.getByDT('conversationWrapper').within(() => {
cy.get('.c-message').last().should('be.visible')
})

cy.getByDT('messageInputWrapper').within(() => {
cy.get('.c-jump-to-latest').should('not.exist')
})
})

it('user2 checks how the infinite scroll works', () => {
switchChannel(additionalChannelName)
switchChannel(CHATROOM_GENERAL_NAME)

cy.getByDT('conversationWrapper').within(() => {
cy.contains('Awesome!').should('be.visible')
})

cy.getByDT('conversationWrapper').scrollTo('top')
cy.giWaitUntilMessagesLoaded()

cy.getByDT('conversationWrapper').within(() => {
cy.get('.c-message:nth-child(2) .c-who > span:first-child').should('contain', user1)
cy.get('.c-message:nth-child(2) .c-notification').should('contain', `Joined ${CHATROOM_GENERAL_NAME}`)
})

cy.giLogout()
})
Expand Down
Loading

0 comments on commit 80c3ffd

Please sign in to comment.