import { describe, it, expect } from 'vitest'; import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import { MessagingProvider } from '../provider'; import { Messenger } from './messenger'; import { MockAdapter } from '../adapters/mock'; function mount() { return render( , ); } describe('Slack-style thread pane', () => { it('opens a thread on 💬, posts a reply into it, and shows the reply count on the parent', async () => { mount(); // Wait for the auto-selected thread's message to render WITH its actions (not just the sidebar // preview), then open the thread pane via the message's reply affordance (💬). const replyButtons = await screen.findAllByTitle('Reply in thread'); fireEvent.click(replyButtons[0]!); expect(await screen.findByText('Thread')).toBeTruthy(); // pane header // The pane's composer (placeholder "Reply…") — send a threaded reply. const replyInput = screen.getByPlaceholderText('Reply…') as HTMLInputElement; fireEvent.change(replyInput, { target: { value: 'on it' } }); // The pane has its own Send; grab the last one (pane is rendered after the main composer). const sends = screen.getAllByText('Send'); fireEvent.click(sends[sends.length - 1]!); // The reply shows in the pane (replies are hidden from the main thread, so this is unique)... await waitFor(() => expect(screen.getByText('on it')).toBeTruthy()); // ...and the parent now advertises the reply count as a thread-link button in the main thread. await waitFor(() => expect(screen.getByRole('button', { name: /1 reply/ })).toBeTruthy()); }); });