From 2c5d39d3312c006c266acdb33dae33bd02b15f8d Mon Sep 17 00:00:00 2001 From: Nuwan Date: Tue, 27 Jan 2026 13:37:31 +0530 Subject: [PATCH] test(08-01): add integration tests for chat window open/close - Expose Redux store for testing (dev/test environments only) - Add 3 tests: window open, window close, placeholder message - Tests verify WindowPortal integration and Redux state updates Co-Authored-By: Claude Sonnet 4.5 --- jam-ui/src/store/store.js | 11 +++- jam-ui/test/chat/chat-window.spec.ts | 81 ++++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 jam-ui/test/chat/chat-window.spec.ts diff --git a/jam-ui/src/store/store.js b/jam-ui/src/store/store.js index cf08603ad..c7abbc614 100644 --- a/jam-ui/src/store/store.js +++ b/jam-ui/src/store/store.js @@ -17,7 +17,7 @@ import mixersReducer from "./features/mixersSlice" import mediaReducer from "./features/mediaSlice" import sessionChatReducer from "./features/sessionChatSlice" -export default configureStore({ +const store = configureStore({ reducer: { textMessage: textMessageReducer, people: peopleReducer, @@ -37,4 +37,11 @@ export default configureStore({ myJamTrack: myJamTracksSlice, jamTrack: jamTrackSlice } -}) \ No newline at end of file +}) + +// Expose store for testing (development and test environments only) +if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') { + window.__REDUX_STORE__ = store; +} + +export default store \ No newline at end of file diff --git a/jam-ui/test/chat/chat-window.spec.ts b/jam-ui/test/chat/chat-window.spec.ts new file mode 100644 index 000000000..ea7fb6940 --- /dev/null +++ b/jam-ui/test/chat/chat-window.spec.ts @@ -0,0 +1,81 @@ +import { test, expect } from '@playwright/test'; +import { loginToJamUI, createAndJoinSession } from '../utils/test-helpers'; + +test.describe('Chat Window', () => { + test.beforeEach(async ({ page }) => { + await loginToJamUI(page); + await createAndJoinSession(page); + }); + + test('opens chat window when dispatching openChatWindow action', async ({ page, context }) => { + // Dispatch openChatWindow action via Redux + await page.evaluate(() => { + const store = (window as any).__REDUX_STORE__; + if (!store) { + throw new Error('Redux store not exposed for testing'); + } + store.dispatch({ type: 'sessionChat/openChatWindow' }); + }); + + // Wait for popup window + const popupPromise = context.waitForEvent('page'); + const popup = await popupPromise; + + // Verify popup opened + expect(popup).toBeTruthy(); + await expect(popup).toHaveTitle('JamKazam Chat'); + + // Verify header content + const header = popup.locator('h5'); + await expect(header).toBeVisible(); + await expect(header).toContainText('Chat'); + }); + + test('closes chat window when clicking close button', async ({ page, context }) => { + // Open chat window + await page.evaluate(() => { + const store = (window as any).__REDUX_STORE__; + store.dispatch({ type: 'sessionChat/openChatWindow' }); + }); + + const popupPromise = context.waitForEvent('page'); + const popup = await popupPromise; + + // Wait for popup to be ready + await popup.waitForLoadState('domcontentloaded'); + + // Click close button + const closeButton = popup.locator('button[aria-label="Close chat"]'); + await expect(closeButton).toBeVisible(); + await closeButton.click(); + + // Verify popup closed (wait a bit for close to complete) + await page.waitForTimeout(1000); + expect(popup.isClosed()).toBe(true); + + // Verify Redux state updated + const isWindowOpen = await page.evaluate(() => { + const store = (window as any).__REDUX_STORE__; + return store.getState().sessionChat.isWindowOpen; + }); + expect(isWindowOpen).toBe(false); + }); + + test('shows placeholder message before messages loaded', async ({ page, context }) => { + // Open chat window + await page.evaluate(() => { + const store = (window as any).__REDUX_STORE__; + store.dispatch({ type: 'sessionChat/openChatWindow' }); + }); + + const popupPromise = context.waitForEvent('page'); + const popup = await popupPromise; + + // Wait for popup to be ready + await popup.waitForLoadState('domcontentloaded'); + + // Verify placeholder text + const placeholder = popup.locator('p:has-text("Chat messages will appear here")'); + await expect(placeholder).toBeVisible(); + }); +});