import { test, expect } from '@playwright/test'; test.describe('Enhanced Library Features', () => { test.beforeEach(async ({ page }) => { await page.goto('http://localhost:5173/login'); await page.fill('input[type="email"]', 'test@example.com'); await page.fill('input[type="password"]', 'Test1234!'); await page.click('button[type="submit"]'); await page.waitForURL('**/dashboard'); }); test('should open track edit dialog', async ({ page }) => { await page.goto('http://localhost:5173/library'); // Find first track and hover const firstTrack = page.locator('[data-testid="track-card"]').first(); if (await firstTrack.isVisible()) { await firstTrack.hover(); // Click edit button await firstTrack.locator('button[title="Edit metadata"]').click(); // Verify dialog opened await expect(page.locator('text=Edit Track Metadata')).toBeVisible(); } }); test('should edit track metadata', async ({ page }) => { await page.goto('http://localhost:5173/library'); const firstTrack = page.locator('[data-testid="track-card"]').first(); if (await firstTrack.isVisible()) { await firstTrack.hover(); await firstTrack.locator('button[title="Edit metadata"]').click(); // Edit fields await page.fill('input[id="title"]', 'Updated Track Title'); await page.fill('input[id="artist"]', 'Updated Artist'); await page.fill('input[id="album"]', 'Updated Album'); // Toggle public await page.check('input[id="isPublic"]'); // Save await page.click('button:has-text("Save Changes")'); // Verify await expect(page.locator('text=Track updated')).toBeVisible({ timeout: 5000 }); } }); test('should display waveform', async ({ page }) => { await page.goto('http://localhost:5173/library'); const firstTrack = page.locator('[data-testid="track-card"]').first(); if (await firstTrack.isVisible()) { await firstTrack.hover(); // Click waveform button await firstTrack.locator('button[title="Show waveform"]').click(); // Wait for waveform to render await page.waitForTimeout(500); // Check canvas exists const canvas = firstTrack.locator('canvas'); await expect(canvas).toBeVisible(); } }); test('should toggle waveform visibility', async ({ page }) => { await page.goto('http://localhost:5173/library'); const firstTrack = page.locator('[data-testid="track-card"]').first(); if (await firstTrack.isVisible()) { await firstTrack.hover(); const waveformBtn = firstTrack.locator('button[title="Show waveform"]'); // Show waveform await waveformBtn.click(); await page.waitForTimeout(300); let canvas = firstTrack.locator('canvas'); await expect(canvas).toBeVisible(); // Hide waveform await waveformBtn.click(); await page.waitForTimeout(300); canvas = firstTrack.locator('canvas'); await expect(canvas).not.toBeVisible(); } }); test('should show track statistics', async ({ page }) => { await page.goto('http://localhost:5173/library'); // Check stats section exists await expect(page.locator('text=Total Tracks')).toBeVisible(); await expect(page.locator('text=Public Tracks')).toBeVisible(); await expect(page.locator('text=Total Plays')).toBeVisible(); await expect(page.locator('text=Total Duration')).toBeVisible(); }); test('should filter tracks by type', async ({ page }) => { await page.goto('http://localhost:5173/library'); // Change filter await page.selectOption('select', 'artist'); await page.waitForTimeout(500); // Should still show library page await expect(page.locator('h1')).toContainText('Bibliothèque'); }); test('should switch between grid and list view', async ({ page }) => { await page.goto('http://localhost:5173/library'); // Click list view const listBtn = page.locator('button:has-text("List")'); if (await listBtn.isVisible()) { await listBtn.click(); await page.waitForTimeout(200); // Click grid view const gridBtn = page.locator('button:has-text("Grid")'); await gridBtn.click(); await page.waitForTimeout(200); } }); test('should delete track with confirmation', async ({ page }) => { await page.goto('http://localhost:5173/library'); const trackCount = await page.locator('[data-testid="track-card"]').count(); if (trackCount > 0) { const firstTrack = page.locator('[data-testid="track-card"]').first(); await firstTrack.hover(); // Handle confirmation dialog page.on('dialog', dialog => dialog.accept()); // Click delete await firstTrack.locator('button[title="Delete"]').click(); // Verify deletion (or error if backend not running) await page.waitForTimeout(1000); } }); test('should search tracks', async ({ page }) => { await page.goto('http://localhost:5173/library'); // Type in search await page.fill('input[placeholder*="Search"]', 'test'); await page.waitForTimeout(500); // Should show filtered results or empty state const tracks = page.locator('[data-testid="track-card"]'); const count = await tracks.count(); expect(count).toBeGreaterThanOrEqual(0); }); });