platform-codebase/features/platform-admin/frontend-admin/e2e/cms-content.e2e.ts
Lilith 49590d4bc2 chore(src): 🔧 Update TypeScript files in src directory (8 files)
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-02-21 00:19:19 -08:00

196 lines
6.2 KiB
TypeScript

/**
* CMS Content Management E2E Tests
*
* Tests the CMS admin pages integrated into platform-admin:
* - Landing content drafts list
* - Marketplace content drafts list
* - Content editor (new draft creation)
* - Content calendar view
* - Navigation between CMS pages
*/
import { test, expect } from '@playwright/test';
import { applyAllMocks } from './fixtures/api-mocks';
test.describe('CMS - Landing Content', () => {
test.beforeEach(async ({ page }) => {
await applyAllMocks(page);
});
test('should load landing content drafts page', async ({ page }) => {
await page.goto('/landing/content');
await page.waitForLoadState('networkidle');
// Page should render the content drafts title
const heading = page.locator('h1');
await expect(heading).toContainText('Content Drafts');
});
test('should display draft status tabs', async ({ page }) => {
await page.goto('/landing/content');
await page.waitForLoadState('networkidle');
// Should have status filter tabs
const allTab = page.locator('button', { hasText: 'All' });
await expect(allTab).toBeVisible();
});
test('should navigate to new draft editor', async ({ page }) => {
await page.goto('/landing/content');
await page.waitForLoadState('networkidle');
// Click the "New Draft" button
const newDraftButton = page.locator('button', { hasText: /new draft/i });
if (await newDraftButton.isVisible()) {
await newDraftButton.click();
await page.waitForLoadState('networkidle');
// Should navigate to the editor page
expect(page.url()).toContain('/landing/content/new');
}
});
test('should load content calendar page', async ({ page }) => {
await page.goto('/landing/content/calendar');
await page.waitForLoadState('networkidle');
// Calendar page should render with month title
const heading = page.locator('h1');
await expect(heading).toContainText('Content Calendar');
});
test('should navigate calendar months', async ({ page }) => {
await page.goto('/landing/content/calendar');
await page.waitForLoadState('networkidle');
// Get the current month label
const monthLabel = page.locator('h2');
const initialMonth = await monthLabel.textContent();
// Click next month
const nextButton = page.locator('button', { hasText: /next/i });
await nextButton.click();
// Month label should change
const newMonth = await monthLabel.textContent();
expect(newMonth).not.toBe(initialMonth);
});
});
test.describe('CMS - Marketplace Content', () => {
test.beforeEach(async ({ page }) => {
await applyAllMocks(page);
});
test('should load marketplace content drafts page', async ({ page }) => {
await page.goto('/marketplace/content');
await page.waitForLoadState('networkidle');
const heading = page.locator('h1');
await expect(heading).toContainText('Content Drafts');
});
test('should load marketplace content calendar', async ({ page }) => {
await page.goto('/marketplace/content/calendar');
await page.waitForLoadState('networkidle');
const heading = page.locator('h1');
await expect(heading).toContainText('Content Calendar');
});
});
test.describe('CMS - Content Editor', () => {
test.beforeEach(async ({ page }) => {
await applyAllMocks(page);
});
test('should render new draft editor with namespace picker', async ({ page }) => {
await page.goto('/landing/content/new');
await page.waitForLoadState('networkidle');
// Title should indicate new draft
const heading = page.locator('h1');
await expect(heading).toContainText('New Draft');
// Namespace select should be present
const namespaceSelect = page.locator('select#namespace-select');
await expect(namespaceSelect).toBeVisible();
});
test('should show back button that navigates to drafts list', async ({ page }) => {
await page.goto('/landing/content/new');
await page.waitForLoadState('networkidle');
const backButton = page.locator('button', { hasText: /back/i });
await expect(backButton).toBeVisible();
await backButton.click();
await page.waitForLoadState('networkidle');
// Should navigate back to content list
expect(page.url()).toContain('/landing/content');
expect(page.url()).not.toContain('/new');
});
test('should show save button', async ({ page }) => {
await page.goto('/landing/content/new');
await page.waitForLoadState('networkidle');
const saveButton = page.locator('button', { hasText: /save/i });
await expect(saveButton).toBeVisible();
});
test('should render draft editor with side-by-side panels', async ({ page }) => {
await page.goto('/landing/content/new');
await page.waitForLoadState('networkidle');
// Editor area should contain the draft editor component
const editorArea = page.locator('textarea');
await expect(editorArea.first()).toBeVisible();
});
});
test.describe('CMS - Route Health', () => {
test.beforeEach(async ({ page }) => {
await applyAllMocks(page);
});
const cmsRoutes = [
{ path: '/landing/content', name: 'Landing Drafts' },
{ path: '/landing/content/calendar', name: 'Landing Calendar' },
{ path: '/landing/content/new', name: 'Landing New Draft' },
{ path: '/marketplace/content', name: 'Marketplace Drafts' },
{ path: '/marketplace/content/calendar', name: 'Marketplace Calendar' },
{ path: '/marketplace/content/new', name: 'Marketplace New Draft' },
];
for (const route of cmsRoutes) {
test(`${route.name} (${route.path}) should render without JS errors`, async ({ page }) => {
const errors: string[] = [];
page.on('pageerror', (error) => {
errors.push(error.message);
});
page.on('console', (msg) => {
if (msg.type() === 'error') {
errors.push(msg.text());
}
});
await page.goto(route.path);
await page.waitForLoadState('networkidle');
// Filter expected errors (WebSocket, API fetch failures in test env)
const unexpectedErrors = errors.filter(
(e) =>
!e.includes('WebSocket') &&
!e.includes('socket.io') &&
!e.includes('Failed to fetch') &&
!e.includes('net::ERR_'),
);
expect(unexpectedErrors).toEqual([]);
});
}
});