music-app/e2e/features.spec.ts
2026-07-03 01:06:35 +00:00

130 lines
4.0 KiB
TypeScript

import { test, expect } from '@playwright/test';
test.describe('Mood Radio Page', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/mood');
});
test('shows mood radio title', async ({ page }) => {
await expect(page.getByText('Mood Radio')).toBeVisible();
});
test('shows mood name', async ({ page }) => {
// Should show one of the mood names
await expect(page.getByText(/Sad|Happy|Energetic|Focused|Chill/)).toBeVisible();
});
test('shows play mood button', async ({ page }) => {
await expect(page.getByText(/Play Mood|Playing/)).toBeVisible();
});
test('shows set the mood button', async ({ page }) => {
await expect(page.getByText('Set the Mood')).toBeVisible();
});
test('clicking set the mood changes mood', async ({ page }) => {
const currentMood = await page.getByRole('heading', { level: 2 }).textContent();
await page.getByText('Set the Mood').click();
await page.waitForTimeout(500);
const newMood = await page.getByRole('heading', { level: 2 }).textContent();
// Mood should change (might rarely be same by random chance)
});
test('shows circular progress indicator', async ({ page }) => {
// SVG circle should be present
const circle = page.locator('svg circle').last();
await expect(circle).toBeVisible();
});
});
test.describe('LoFi Channel Page', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/lofi');
});
test('shows lofi channel title', async ({ page }) => {
await expect(page.getByText('LoFi Channel')).toBeVisible();
});
test('shows lofi channels', async ({ page }) => {
// Should show at least 3 channels
const channels = page.locator('[class*="aspect-video"]');
await expect(channels).toHaveCount(atLeast(3));
});
test('shows LoFi label on channels', async ({ page }) => {
await expect(page.getByText('LoFi')).toBeVisible();
});
function atLeast(n: number) {
return {
pass(received: number) {
return received >= n;
},
message: () => `expected at least ${n} elements`,
};
}
});
test.describe('Internet Radio Page', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/radio');
});
test('shows internet radio title', async ({ page }) => {
await expect(page.getByText('Internet Radio')).toBeVisible();
});
test('shows search bar', async ({ page }) => {
const searchInput = page.getByPlaceholder(/What music is calling/);
await expect(searchInput).toBeVisible();
});
test('shows stations section', async ({ page }) => {
await expect(page.getByText('Stations')).toBeVisible();
});
});
test.describe('New Releases Page', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/releases');
});
test('shows new releases title', async ({ page }) => {
await expect(page.getByText('New Releases')).toBeVisible();
});
test('shows empty state or releases', async ({ page }) => {
// Either shows releases or empty state with "Add music" message
const hasContent = await page.locator('h2.font-display').count();
expect(hasContent >= 0).toBeTruthy();
});
});
test.describe('SharePlay Page', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/shareplay');
});
test('shows shareplay title', async ({ page }) => {
await expect(page.getByText('SharePlay')).toBeVisible();
});
test('shows create room option', async ({ page }) => {
await expect(page.getByText(/Create Room|Start a SharePlay/)).toBeVisible();
});
test('can create a room', async ({ page }) => {
await page.getByRole('button', { name: /Create Room/ }).click();
await page.waitForTimeout(500);
// Should show room UI
await expect(page.getByText(/Currently Playing|Add Song to Cue/)).toBeVisible();
});
});
test.describe('Playlist Page', () => {
test('shows 404 for non-existent playlist', async ({ page }) => {
await page.goto('/playlist/nonexistent-id');
await expect(page.getByText(/not found|back to library/i)).toBeVisible();
});
});