diff --git a/cypress/e2e/chat/Avatar.feature b/cypress/e2e/chat/Avatar.feature new file mode 100644 index 000000000..9ca2141dc --- /dev/null +++ b/cypress/e2e/chat/Avatar.feature @@ -0,0 +1,26 @@ +Feature: Chat Avatars + As a user + I want to see avatars for all chat participants + So that I can visually identify who I am chatting with + + Background: + Given the following "users" are in the database: + | slug | email | password | id | name | termsAndConditionsAgreedVersion | + | alice | alice@example.org | 1234 | alice | Alice | 0.0.4 | + | bob | bob@example.org | 1234 | bob | Bob | 0.0.4 | + + Scenario: Room list shows avatar for each room + Given "alice" sends a chat message "Hello" to "bob" + And I am logged in as "bob" + And I navigate to page "/chat" + Then I see an avatar in the room list + + Scenario: Messages show avatar for other user and own messages + Given "alice" sends a chat message "Hello" to "bob" + And I am logged in as "bob" + And I navigate to page "/chat" + When I click on the room "Alice" + Then I see the message "Hello" in the chat + And I see an avatar for the other user's message + When I send the message "Hi Alice!" in the chat + Then I see an avatar for my own message diff --git a/cypress/e2e/chat/ExternalRoom.feature b/cypress/e2e/chat/ExternalRoom.feature new file mode 100644 index 000000000..436b5e695 --- /dev/null +++ b/cypress/e2e/chat/ExternalRoom.feature @@ -0,0 +1,29 @@ +Feature: External Room Creation + As a user + I want incoming messages from new users to appear in my room list + Without losing focus on my current conversation + + Background: + Given the following "users" are in the database: + | slug | email | password | id | name | termsAndConditionsAgreedVersion | + | alice | alice@example.org | 1234 | alice | Alice | 0.0.4 | + | bob | bob@example.org | 1234 | bob | Bob | 0.0.4 | + | charlie | charlie@example.org | 1234 | charlie | Charlie | 0.0.4 | + + Scenario: New room from external message does not steal focus + Given "alice" sends a chat message "Hi Bob!" to "bob" + And I am logged in as "bob" + And I navigate to page "/chat" + And I click on the room "Alice" + And I see the message "Hi Bob!" in the chat + When "charlie" sends a chat message "Surprise!" to "bob" + Then I see "Charlie" in the room list + And I still see the message "Hi Bob!" in the chat + + Scenario: New room from external message shows unread badge + Given "alice" sends a chat message "Hi Bob!" to "bob" + And I am logged in as "bob" + And I navigate to page "/chat" + And I click on the room "Alice" + When "charlie" sends a chat message "Surprise!" to "bob" + Then I see 1 unread chat message in the header diff --git a/cypress/e2e/chat/FileMessage.feature b/cypress/e2e/chat/FileMessage.feature new file mode 100644 index 000000000..2123ad213 --- /dev/null +++ b/cypress/e2e/chat/FileMessage.feature @@ -0,0 +1,17 @@ +Feature: File Messages + As a user + I want to send files and audio messages in chat + So that I can share media with other users + + Background: + Given the following "users" are in the database: + | slug | email | password | id | name | termsAndConditionsAgreedVersion | + | alice | alice@example.org | 1234 | alice | Alice | 0.0.4 | + | bob | bob@example.org | 1234 | bob | Bob | 0.0.4 | + + Scenario: File message shows filename in room preview + Given I am logged in as "alice" + And I navigate to page "/chat?userId=bob" + When I upload the file "humanconnection.png" in the chat + Then I see the room preview contains "humanconnection" + diff --git a/cypress/e2e/chat/GroupChat.feature b/cypress/e2e/chat/GroupChat.feature index 7784cdee7..75e4bce1c 100644 --- a/cypress/e2e/chat/GroupChat.feature +++ b/cypress/e2e/chat/GroupChat.feature @@ -35,3 +35,11 @@ Feature: Group Chat And I see no unread chat messages in the header When "alice" sends a group chat message "Hello everyone!" to "test-group" Then I see 1 unread chat message in the header + + Scenario: Group room shows group icon before name in room list + Given "bob" is a member of group "test-group" + And "alice" opens the group chat for "test-group" + And "alice" sends a group chat message "Hello group" to "test-group" + And I am logged in as "bob" + And I navigate to page "/chat" + Then I see a group icon before "Test Group" in the room list diff --git a/cypress/e2e/chat/RoomFilter.feature b/cypress/e2e/chat/RoomFilter.feature new file mode 100644 index 000000000..a578f991f --- /dev/null +++ b/cypress/e2e/chat/RoomFilter.feature @@ -0,0 +1,31 @@ +Feature: Chat Room Filter + As a user + I want to filter chat rooms by name + So that I can quickly find a conversation + + Background: + Given the following "users" are in the database: + | slug | email | password | id | name | termsAndConditionsAgreedVersion | + | alice | alice@example.org | 1234 | alice | Alice | 0.0.4 | + | bob | bob@example.org | 1234 | bob | Bob | 0.0.4 | + | charlie | charlie@example.org | 1234 | charlie | Charlie | 0.0.4 | + And "alice" sends a chat message "Hi Bob" to "bob" + And "charlie" sends a chat message "Hi Bob" to "bob" + + Scenario: Filter rooms by name + Given I am logged in as "bob" + And I navigate to page "/chat" + Then I see "Charlie" in the room list + And I see "Alice" in the room list + When I type "Ali" in the room filter + Then I see "Alice" in the room list + And I do not see "Charlie" in the room list + + Scenario: Clear filter restores all rooms + Given I am logged in as "bob" + And I navigate to page "/chat" + When I type "Ali" in the room filter + Then I see "Alice" in the room list + When I clear the room filter + Then I see "Alice" in the room list + And I see "Charlie" in the room list diff --git a/cypress/support/step_definitions/chat/Avatar/I_see_an_avatar_for_the_message.js b/cypress/support/step_definitions/chat/Avatar/I_see_an_avatar_for_the_message.js new file mode 100644 index 000000000..f51f4d8b5 --- /dev/null +++ b/cypress/support/step_definitions/chat/Avatar/I_see_an_avatar_for_the_message.js @@ -0,0 +1,33 @@ +import { defineStep } from '@badeball/cypress-cucumber-preprocessor' + +defineStep("I see an avatar for the other user's message", () => { + // Other user's messages are on the left side (no vac-offset-current class) + // The avatar may be in light DOM (our ProfileAvatar slot) or shadow DOM (library default) + cy.get('vue-advanced-chat', { timeout: 15000 }).then(($el) => { + const shadow = $el[0].shadowRoot + const messageWrappers = shadow.querySelectorAll('.vac-message-wrapper') + const otherUserMsg = Array.from(messageWrappers).find( + (el) => !el.querySelector('.vac-offset-current'), + ) + expect(otherUserMsg).to.exist + // Check for avatar in shadow DOM or light DOM slot content + const hasAvatar = + otherUserMsg.querySelector('.vac-avatar') || + $el.find('.profile-avatar.vac-message-avatar').length > 0 + expect(hasAvatar).to.be.ok + }) +}) + +defineStep('I see an avatar for my own message', () => { + // Own messages are on the right side (vac-offset-current class) + cy.get('vue-advanced-chat', { timeout: 15000 }).then(($el) => { + const shadow = $el[0].shadowRoot + const ownMsg = shadow.querySelector('.vac-offset-current') + expect(ownMsg).to.exist + // Check for avatar in shadow DOM or light DOM slot content + const hasAvatar = + shadow.querySelector('.vac-avatar-current') || + $el.find('.profile-avatar.vac-message-avatar').length > 0 + expect(hasAvatar).to.be.ok + }) +}) diff --git a/cypress/support/step_definitions/chat/Avatar/I_see_an_avatar_with_initials_in_the_room_list.js b/cypress/support/step_definitions/chat/Avatar/I_see_an_avatar_with_initials_in_the_room_list.js new file mode 100644 index 000000000..eea15dc5e --- /dev/null +++ b/cypress/support/step_definitions/chat/Avatar/I_see_an_avatar_with_initials_in_the_room_list.js @@ -0,0 +1,8 @@ +import { defineStep } from '@badeball/cypress-cucumber-preprocessor' + +defineStep('I see an avatar in the room list', () => { + // Room list avatar slots are in the light DOM of vue-advanced-chat + cy.get('vue-advanced-chat .profile-avatar', { timeout: 15000 }) + .first() + .should('be.visible') +}) diff --git a/cypress/support/step_definitions/chat/ExternalRoom/I_still_see_the_message_{string}_in_the_chat.js b/cypress/support/step_definitions/chat/ExternalRoom/I_still_see_the_message_{string}_in_the_chat.js new file mode 100644 index 000000000..64ef7fb0c --- /dev/null +++ b/cypress/support/step_definitions/chat/ExternalRoom/I_still_see_the_message_{string}_in_the_chat.js @@ -0,0 +1,8 @@ +import { defineStep } from '@badeball/cypress-cucumber-preprocessor' + +defineStep('I still see the message {string} in the chat', (message) => { + cy.get('vue-advanced-chat', { timeout: 15000 }) + .shadow() + .find('.vac-message-wrapper', { timeout: 10000 }) + .should('contain', message) +}) diff --git a/cypress/support/step_definitions/chat/FileMessage/I_see_the_room_preview_contains_{string}.js b/cypress/support/step_definitions/chat/FileMessage/I_see_the_room_preview_contains_{string}.js new file mode 100644 index 000000000..d77a44726 --- /dev/null +++ b/cypress/support/step_definitions/chat/FileMessage/I_see_the_room_preview_contains_{string}.js @@ -0,0 +1,18 @@ +import { defineStep } from '@badeball/cypress-cucumber-preprocessor' + +defineStep('I see the room preview contains {string}', (text) => { + cy.get('vue-advanced-chat', { timeout: 15000 }) + .shadow() + .find('.vac-room-item', { timeout: 10000 }) + .first() + .should('contain', text) +}) + +defineStep('I see the room preview contains a microphone icon', () => { + cy.get('vue-advanced-chat', { timeout: 15000 }) + .shadow() + .find('.vac-room-item', { timeout: 10000 }) + .first() + .find('.vac-icon-microphone, #vac-icon-microphone') + .should('exist') +}) diff --git a/cypress/support/step_definitions/chat/FileMessage/I_upload_the_file_{string}_in_the_chat.js b/cypress/support/step_definitions/chat/FileMessage/I_upload_the_file_{string}_in_the_chat.js new file mode 100644 index 000000000..8102628e8 --- /dev/null +++ b/cypress/support/step_definitions/chat/FileMessage/I_upload_the_file_{string}_in_the_chat.js @@ -0,0 +1,20 @@ +import { defineStep } from '@badeball/cypress-cucumber-preprocessor' + +defineStep('I upload the file {string} in the chat', (filename) => { + cy.get('vue-advanced-chat', { timeout: 15000 }) + .shadow() + .find('.vac-svg-button', { timeout: 10000 }) + .filter(':has(#vac-icon-paperclip)') + .click() + + cy.get('vue-advanced-chat') + .shadow() + .find('input[type="file"]', { timeout: 5000 }) + .selectFile(`cypress/fixtures/${filename}`, { force: true }) + + // Wait for file preview and click send + cy.get('vue-advanced-chat') + .shadow() + .find('.vac-icon-send, .vac-svg-button:has(#vac-icon-send)', { timeout: 10000 }) + .click() +}) diff --git a/cypress/support/step_definitions/chat/GroupChat/I_see_a_group_icon_before_{string}_in_the_room_list.js b/cypress/support/step_definitions/chat/GroupChat/I_see_a_group_icon_before_{string}_in_the_room_list.js new file mode 100644 index 000000000..693b26e33 --- /dev/null +++ b/cypress/support/step_definitions/chat/GroupChat/I_see_a_group_icon_before_{string}_in_the_room_list.js @@ -0,0 +1,10 @@ +import { defineStep } from '@badeball/cypress-cucumber-preprocessor' + +defineStep('I see a group icon before {string} in the room list', (name) => { + // Group room info slots are in the light DOM + cy.get('vue-advanced-chat .room-name-with-icon', { timeout: 15000 }) + .contains(name) + .parent() + .find('.room-group-icon') + .should('exist') +}) diff --git a/cypress/support/step_definitions/chat/RoomFilter/I_clear_the_room_filter.js b/cypress/support/step_definitions/chat/RoomFilter/I_clear_the_room_filter.js new file mode 100644 index 000000000..46677b2c5 --- /dev/null +++ b/cypress/support/step_definitions/chat/RoomFilter/I_clear_the_room_filter.js @@ -0,0 +1,9 @@ +import { defineStep } from '@badeball/cypress-cucumber-preprocessor' + +defineStep('I clear the room filter', () => { + cy.get('vue-advanced-chat', { timeout: 15000 }) + .shadow() + .find('input[type="search"]', { timeout: 10000 }) + .focus() + .type('{selectall}{del}', { force: true }) +}) diff --git a/cypress/support/step_definitions/chat/RoomFilter/I_type_{string}_in_the_room_filter.js b/cypress/support/step_definitions/chat/RoomFilter/I_type_{string}_in_the_room_filter.js new file mode 100644 index 000000000..b7cbbf166 --- /dev/null +++ b/cypress/support/step_definitions/chat/RoomFilter/I_type_{string}_in_the_room_filter.js @@ -0,0 +1,9 @@ +import { defineStep } from '@badeball/cypress-cucumber-preprocessor' + +defineStep('I type {string} in the room filter', (text) => { + cy.get('vue-advanced-chat', { timeout: 15000 }) + .shadow() + .find('input[type="search"]', { timeout: 10000 }) + .should('be.visible') + .type(text) +}) diff --git a/cypress/support/step_definitions/common/I_see_{string}_in_the_room_list.js b/cypress/support/step_definitions/common/I_see_{string}_in_the_room_list.js new file mode 100644 index 000000000..600412996 --- /dev/null +++ b/cypress/support/step_definitions/common/I_see_{string}_in_the_room_list.js @@ -0,0 +1,17 @@ +import { defineStep } from '@badeball/cypress-cucumber-preprocessor' + +defineStep('I see {string} in the room list', (name) => { + cy.get('vue-advanced-chat', { timeout: 15000 }) + .shadow() + .find('.vac-room-item', { timeout: 10000 }) + .contains(name) + .should('be.visible') +}) + +defineStep('I do not see {string} in the room list', (name) => { + cy.get('vue-advanced-chat', { timeout: 15000 }) + .shadow() + .find('.vac-room-item', { timeout: 10000 }) + .contains(name) + .should('not.exist') +})