test(09-02): add integration tests for receive message flow

- Test WebSocket message display with sender info
- Test message deduplication (sent message not duplicated on WebSocket receive)
- Test auto-scroll to bottom on new message
- Test unread badge increment when window closed
- 4 comprehensive tests for real-time receive scenarios
This commit is contained in:
Nuwan 2026-01-27 19:48:16 +05:30
parent 9eb58bd02b
commit 984c60c656
1 changed files with 153 additions and 0 deletions

View File

@ -0,0 +1,153 @@
import { test, expect } from '@playwright/test';
import { loginToJamUI, createAndJoinSession } from '../utils/test-helpers';
test.describe('Receive Message', () => {
test.beforeEach(async ({ page }) => {
await loginToJamUI(page);
await createAndJoinSession(page);
// Open chat window
const chatButton = page.locator('img[alt="Chat"]');
await chatButton.click();
});
test('displays message received via WebSocket', async ({ page, context }) => {
const popupPromise = context.waitForEvent('page');
const popup = await popupPromise;
await popup.waitForLoadState('domcontentloaded');
// Simulate receiving message via WebSocket (dispatch Redux action)
await page.evaluate(() => {
const store = (window as any).__REDUX_STORE__;
// Simulate WebSocket message
store.dispatch({
type: 'sessionChat/addMessageFromWebSocket',
payload: {
id: 'test-msg-123',
senderId: 'other-user-id',
senderName: 'Test User',
message: 'Hello from WebSocket!',
createdAt: new Date().toISOString(),
channel: 'test-session-id'
}
});
});
// Wait for message to appear in popup
await popup.waitForTimeout(500);
const message = popup.locator('text=Hello from WebSocket!');
await expect(message).toBeVisible();
// Verify sender name displayed
const sender = popup.locator('text=Test User');
await expect(sender).toBeVisible();
});
test('does not duplicate sent message when received via WebSocket', async ({ page, context }) => {
const popupPromise = context.waitForEvent('page');
const popup = await popupPromise;
await popup.waitForLoadState('domcontentloaded');
// Send message
const textarea = popup.locator('textarea[placeholder*="Type a message"]');
await textarea.fill('No duplicate test');
const sendButton = popup.locator('button:has-text("Send")');
await sendButton.click();
// Wait for optimistic update
await popup.waitForTimeout(300);
// Simulate receiving same message via WebSocket (with same msg_id)
await page.evaluate(() => {
const store = (window as any).__REDUX_STORE__;
const state = store.getState();
// Get the message that was just sent (will have msg_id from server)
const messages = state.sessionChat.messagesByChannel['test-session-id'] || [];
const lastMessage = messages[messages.length - 1];
// Try to add again via WebSocket (should be deduplicated)
if (lastMessage) {
store.dispatch({
type: 'sessionChat/addMessageFromWebSocket',
payload: lastMessage
});
}
});
await popup.waitForTimeout(300);
// Should only have ONE instance of the message
const messages = popup.locator('text=No duplicate test');
expect(await messages.count()).toBe(1);
});
test('auto-scrolls to bottom when new message received', async ({ page, context }) => {
const popupPromise = context.waitForEvent('page');
const popup = await popupPromise;
await popup.waitForLoadState('domcontentloaded');
// Add multiple messages to enable scrolling
for (let i = 1; i <= 10; i++) {
await page.evaluate((num) => {
const store = (window as any).__REDUX_STORE__;
store.dispatch({
type: 'sessionChat/addMessageFromWebSocket',
payload: {
id: `msg-${num}`,
senderId: 'user-id',
senderName: 'Test User',
message: `Message ${num}`,
createdAt: new Date().toISOString(),
channel: 'test-session-id'
}
});
}, i);
await popup.waitForTimeout(100);
}
// Last message should be visible (auto-scrolled)
const lastMessage = popup.locator('text=Message 10');
await expect(lastMessage).toBeVisible();
});
test('increments unread badge when message received and window closed', async ({ page, context }) => {
// Open then close chat window
const chatButton = page.locator('img[alt="Chat"]');
await chatButton.click();
const popupPromise = context.waitForEvent('page');
const popup = await popupPromise;
await popup.waitForLoadState('domcontentloaded');
// Close window
const closeButton = popup.locator('button[aria-label="Close chat"]');
await closeButton.click();
await page.waitForTimeout(500);
// Simulate receiving message while window closed
await page.evaluate(() => {
const store = (window as any).__REDUX_STORE__;
store.dispatch({
type: 'sessionChat/addMessageFromWebSocket',
payload: {
id: 'msg-closed-window',
senderId: 'other-user',
senderName: 'Test User',
message: 'Message while closed',
createdAt: new Date().toISOString(),
channel: 'test-session-id'
}
});
});
await page.waitForTimeout(300);
// Unread badge should show "1"
const badge = page.locator('div:has-text("1")').filter({ hasText: /^1$/ });
await expect(badge).toBeVisible();
});
});