more chat e2e tests

This commit is contained in:
Ulf Gebhardt 2026-04-04 04:46:50 +02:00
parent 586eaedd59
commit f862bf4018
Signed by: ulfgebhardt
GPG Key ID: DA6B843E748679C9
14 changed files with 243 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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
})
})

View File

@ -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')
})

View File

@ -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)
})

View File

@ -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')
})

View File

@ -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()
})

View File

@ -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')
})

View File

@ -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 })
})

View File

@ -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)
})

View File

@ -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')
})