- Next.js 14+ with App Router and TypeScript - Tailwind CSS and ShadCN UI styling - Zustand state management - Dexie.js for IndexedDB (local-first data) - Auth.js v5 for authentication - BMAD framework integration Co-Authored-By: Claude <noreply@anthropic.com>
78 lines
3.0 KiB
TypeScript
78 lines
3.0 KiB
TypeScript
import { test, expect } from '../support/fixtures';
|
|
|
|
test.describe('Chat Interface (Story 1.2)', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
// GIVEN: User is on the homepage
|
|
await page.goto('/');
|
|
});
|
|
|
|
test('[P0] should allow user to send a message', async ({ page }) => {
|
|
// GIVEN: Input field is visible
|
|
const input = page.getByTestId('chat-input');
|
|
const sendButton = page.getByTestId('send-button');
|
|
|
|
// WHEN: User types "Hello" and clicks send
|
|
await input.fill('Hello World');
|
|
await sendButton.click();
|
|
|
|
// THEN: Input should be cleared
|
|
await expect(input).toHaveValue('');
|
|
|
|
// THEN: Message should appear in the chat
|
|
// We look for the bubble with the specific text
|
|
// Note: The app might render markdown, so exact text match usually works
|
|
await expect(page.getByTestId('chat-bubble-user')).toContainText('Hello World');
|
|
});
|
|
|
|
test('[P0] should display AI typing indicator', async ({ page }) => {
|
|
// This test relies on the simulation delay added in the store
|
|
|
|
// WHEN: User sends a message
|
|
await page.getByTestId('chat-input').fill('Tell me a story');
|
|
await page.getByTestId('send-button').click();
|
|
|
|
// THEN: Typing indicator should appear immediately (before AI response)
|
|
const indicator = page.getByTestId('typing-indicator');
|
|
await expect(indicator).toBeVisible();
|
|
|
|
// THEN: Typing indicator should disappear eventually (after response)
|
|
// The delay is simulated as 1000-2000ms in the store
|
|
await expect(indicator).toBeHidden({ timeout: 5000 });
|
|
|
|
// THEN: AI response should appear
|
|
await expect(page.getByTestId('chat-bubble-ai')).toBeVisible();
|
|
});
|
|
|
|
test('[P0] should persist messages across reload', async ({ page }) => {
|
|
// GIVEN: User sends a message
|
|
const uniqueMessage = `Persistence Test ${Date.now()}`;
|
|
await page.getByTestId('chat-input').fill(uniqueMessage);
|
|
await page.getByTestId('send-button').click();
|
|
|
|
// Wait for message to appear
|
|
await expect(page.getByText(uniqueMessage)).toBeVisible();
|
|
|
|
// WHEN: Page is reloaded
|
|
await page.reload();
|
|
|
|
// THEN: Message should still be visible
|
|
await expect(page.getByText(uniqueMessage)).toBeVisible();
|
|
});
|
|
|
|
test('[P1] should adapt to mobile viewport', async ({ page }) => {
|
|
// GIVEN: Mobile viewport
|
|
await page.setViewportSize({ width: 375, height: 667 });
|
|
|
|
// WHEN: Page loads
|
|
await page.goto('/');
|
|
|
|
// THEN: Important elements are visible
|
|
await expect(page.getByTestId('chat-input')).toBeVisible();
|
|
await expect(page.getByTestId('send-button')).toBeVisible();
|
|
|
|
// Check elements fit within width (approximate check)
|
|
const inputBox = await page.getByTestId('chat-input').boundingBox();
|
|
expect(inputBox?.width).toBeLessThan(375); // Should have padding
|
|
});
|
|
});
|