93 lines
3.7 KiB
TypeScript
93 lines
3.7 KiB
TypeScript
|
|
import { test, expect } from './fixtures';
|
|
|
|
test.describe('VII. AI Coach Features', () => {
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/');
|
|
});
|
|
|
|
// Helper to handle first login if needed (copied from core-auth)
|
|
async function handleFirstLogin(page: any) {
|
|
try {
|
|
const heading = page.getByRole('heading', { name: /Change Password/i });
|
|
const dashboard = page.getByText('Free Workout');
|
|
|
|
await expect(heading).toBeVisible({ timeout: 5000 });
|
|
await page.getByLabel('New Password').fill('StrongNewPass123!');
|
|
await page.getByRole('button', { name: /Save|Change/i }).click();
|
|
await expect(dashboard).toBeVisible();
|
|
} catch (e) {
|
|
if (await page.getByText('Free Workout').isVisible()) return;
|
|
}
|
|
}
|
|
|
|
test('7.1 AI Coach - Basic Conversation & Markdown', async ({ page, createUniqueUser }) => {
|
|
const user = await createUniqueUser();
|
|
// Login
|
|
await page.getByLabel('Email').fill(user.email);
|
|
await page.getByLabel('Password').fill(user.password);
|
|
await page.getByRole('button', { name: 'Login' }).click();
|
|
await handleFirstLogin(page);
|
|
|
|
// Navigate to AI Coach
|
|
await page.getByText('AI Coach').click();
|
|
|
|
// Type message
|
|
const input = page.getByPlaceholder(/Ask your AI coach/i);
|
|
await input.fill('How to do a pushup?');
|
|
await page.getByRole('button', { name: /Send/i }).click();
|
|
|
|
// Verify response (Mocked or Real - expecting Real from previous context)
|
|
// Since we can't easily mock backend without more setup, we wait for *any* response
|
|
await expect(page.locator('.prose')).toBeVisible({ timeout: 15000 });
|
|
|
|
// Check for markdown rendering (e.g., strong tags or list items if AI returns them)
|
|
// This is a bit flaky with real AI, but checking for visibility is a good start.
|
|
});
|
|
|
|
test('7.2, 7.3, 7.4 AI Coach - Bookmark Flow', async ({ page, createUniqueUser }) => {
|
|
const user = await createUniqueUser();
|
|
// Login
|
|
await page.getByLabel('Email').fill(user.email);
|
|
await page.getByLabel('Password').fill(user.password);
|
|
await page.getByRole('button', { name: 'Login' }).click();
|
|
await handleFirstLogin(page);
|
|
|
|
await page.getByText('AI Coach').click();
|
|
|
|
// Send message
|
|
await page.getByPlaceholder(/Ask your AI coach/i).fill('Tell me a short fitness tip');
|
|
await page.getByRole('button', { name: /Send/i }).click();
|
|
|
|
// Wait for response bubble
|
|
const responseBubble = page.locator('.prose').first();
|
|
await expect(responseBubble).toBeVisible({ timeout: 15000 });
|
|
|
|
// 7.2 Bookmark
|
|
// Find bookmark button within the message container.
|
|
// Assuming the layout puts actions near the message.
|
|
// We look for the Bookmark icon button.
|
|
const bookmarkBtn = page.getByRole('button', { name: /Bookmark/i }).first();
|
|
await bookmarkBtn.click();
|
|
|
|
// Expect success snackbar
|
|
await expect(page.getByText(/Message saved/i)).toBeVisible();
|
|
|
|
// 7.3 View Saved
|
|
await page.getByRole('button', { name: /Saved/i }).click(); // The TopBar action
|
|
await expect(page.getByText('Saved Messages')).toBeVisible(); // Sheet title
|
|
|
|
// Verify content is there
|
|
await expect(page.getByText(/fitness tip/i)).toBeVisible(); // Part of our prompt/response context usually
|
|
|
|
// 7.4 Delete Bookmark
|
|
const deleteBtn = page.getByRole('button', { name: /Delete/i }).first();
|
|
await deleteBtn.click();
|
|
|
|
// Verify removal
|
|
await expect(deleteBtn).not.toBeVisible();
|
|
});
|
|
|
|
});
|