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