import { test, expect } from '@playwright/test' test.describe('Collections List Page', () => { test.beforeEach(async ({ page }) => { await page.goto('/collections') }) test('should display collections page header', async ({ page }) => { const heading = page.getByRole('heading', { name: /collections|tabatafit admin/i }) await expect(heading).toBeVisible() }) test('should have Add Collection button', async ({ page }) => { const url = page.url() if (!url.includes('/collections')) return const addButton = page.getByRole('button', { name: /add collection/i }) await expect(addButton).toBeVisible() }) test('should display subtitle text', async ({ page }) => { const url = page.url() if (!url.includes('/collections')) return await expect(page.getByText(/organize workouts into collections/i)).toBeVisible() }) test('should display collection cards after loading', async ({ page }) => { const url = page.url() if (!url.includes('/collections')) return // Wait for loading to finish await page.waitForSelector('[class*="animate-spin"]', { state: 'detached', timeout: 10000 }).catch(() => {}) // Should show collection cards in a grid layout const grid = page.locator('[class*="grid"]') await expect(grid).toBeVisible() }) test('should display collection title and description on cards', async ({ page }) => { const url = page.url() if (!url.includes('/collections')) return await page.waitForSelector('[class*="animate-spin"]', { state: 'detached', timeout: 10000 }).catch(() => {}) // Find collection cards const cards = page.locator('[class*="bg-neutral-900"]').filter({ has: page.locator('h3') }) const count = await cards.count() if (count > 0) { const firstCard = cards.first() // Card should have a title (h3) await expect(firstCard.locator('h3')).toBeVisible() // Card should have description text (p element) const description = firstCard.locator('p').first() await expect(description).toBeVisible() } }) test('should display collection icon', async ({ page }) => { const url = page.url() if (!url.includes('/collections')) return await page.waitForSelector('[class*="animate-spin"]', { state: 'detached', timeout: 10000 }).catch(() => {}) // Icon containers have specific styling const iconContainers = page.locator('[class*="w-12"][class*="h-12"][class*="rounded-xl"]') const count = await iconContainers.count() if (count > 0) { await expect(iconContainers.first()).toBeVisible() } }) test('should display gradient bars for collections that have them', async ({ page }) => { const url = page.url() if (!url.includes('/collections')) return await page.waitForSelector('[class*="animate-spin"]', { state: 'detached', timeout: 10000 }).catch(() => {}) // Gradient bars have inline background style with linear-gradient const gradientBars = page.locator('[class*="h-2"][class*="rounded-full"]') const count = await gradientBars.count() // Gradient bars are optional (only shown if collection has gradient property) if (count > 0) { const firstBar = gradientBars.first() const style = await firstBar.getAttribute('style') expect(style).toContain('linear-gradient') } }) test('should have edit and delete buttons on cards', async ({ page }) => { const url = page.url() if (!url.includes('/collections')) return await page.waitForSelector('[class*="animate-spin"]', { state: 'detached', timeout: 10000 }).catch(() => {}) const editButtons = page.locator('button').filter({ has: page.locator('svg.lucide-edit') }) const deleteButtons = page.locator('button').filter({ has: page.locator('svg.lucide-trash-2') }) const editCount = await editButtons.count() const deleteCount = await deleteButtons.count() // If collections are displayed, they should have action buttons if (editCount > 0) { expect(editCount).toBeGreaterThan(0) expect(deleteCount).toBeGreaterThan(0) // Each collection should have both edit and delete expect(editCount).toBe(deleteCount) } }) }) test.describe('Collections Page Loading State', () => { test('should show loading spinner initially', async ({ page }) => { // Navigate and check for spinner before data loads await page.goto('/collections') const url = page.url() if (!url.includes('/collections')) return // The spinner might be very brief, so we just verify the page loads await page.waitForLoadState('networkidle') // After loading, spinner should be gone const spinner = page.locator('[class*="animate-spin"]') await expect(spinner).not.toBeVisible({ timeout: 10000 }) }) })