test: add E2E test for themes CRUD (GAP-06)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>master
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…
Reference in New Issue