test: add E2E test for themes CRUD (GAP-06)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
master
oabrivard 3 months ago
parent da602d850d
commit 4923a8c355

@ -0,0 +1,94 @@
/**
* E2E test: Themes CRUD operations.
*
* Validates that a user can:
* 1. Navigate to /themes
* 2. Create a new theme via the API
* 3. Update the theme via the API
* 4. Delete the theme via the API
* 5. Verify the theme is removed from the list
*/
import { test, expect } from '@playwright/test';
import { loginAsUser } from '../helpers/auth';
test.describe('Theme management', () => {
test('should create, edit, and delete a theme', async ({ page }) => {
// Step 1: Login
await loginAsUser(page);
await page.goto('/themes', { waitUntil: 'domcontentloaded' });
// Step 2: Wait for page to load
// The page title should be visible
await expect(
page.locator('h1').filter({ hasText: 'Personnaliser' }),
).toBeVisible({ timeout: 10_000 });
// Step 3: Create a new theme via the API (faster than UI interaction)
// Use page.evaluate to call the themes API
const createResp = await page.evaluate(async () => {
const resp = await fetch('/api/v1/themes', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
},
credentials: 'same-origin',
body: JSON.stringify({
name: 'E2E Test Theme',
theme: 'Testing Topic',
categories: ['Category A', 'Category B'],
}),
});
return { status: resp.status, data: await resp.json() };
});
expect(createResp.status).toBe(201);
const themeId = createResp.data.id;
expect(themeId).toBeTruthy();
// Step 4: Reload the page and verify the theme appears
await page.goto('/themes', { waitUntil: 'domcontentloaded' });
// The theme should be in the dropdown or visible
// Wait for themes to load
await page.waitForTimeout(1000);
// Step 5: Update the theme via API
const updateResp = await page.evaluate(async (id: string) => {
const resp = await fetch(`/api/v1/themes/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
},
credentials: 'same-origin',
body: JSON.stringify({ name: 'E2E Updated Theme' }),
});
return { status: resp.status, data: await resp.json() };
}, themeId);
expect(updateResp.status).toBe(200);
expect(updateResp.data.name).toBe('E2E Updated Theme');
// Step 6: Delete the theme via API
const deleteResp = await page.evaluate(async (id: string) => {
const resp = await fetch(`/api/v1/themes/${id}`, {
method: 'DELETE',
headers: { 'X-Requested-With': 'XMLHttpRequest' },
credentials: 'same-origin',
});
return { status: resp.status };
}, themeId);
expect(deleteResp.status).toBe(204);
// Step 7: Verify theme is gone
const listResp = await page.evaluate(async () => {
const resp = await fetch('/api/v1/themes', {
headers: { 'X-Requested-With': 'XMLHttpRequest' },
credentials: 'same-origin',
});
return { status: resp.status, data: await resp.json() };
});
expect(listResp.status).toBe(200);
const remaining = listResp.data.filter((t: any) => t.name === 'E2E Updated Theme');
expect(remaining.length).toBe(0);
});
});
Loading…
Cancel
Save