test: CMP E2E tests — Dashboard (20 tests) + EWR/Consent (19 tests)
cmp-dashboard.spec.ts (235 LOC, 20 tests): - Page load, KPI cards, site selector - Module navigation grid (8 modules) - Compliance checklist (9 DSGVO items) - Cookie category acceptance bars cmp-ewr-consent.spec.ts (285 LOC, 19 tests): - First visit banner appearance - EWR-Only toggle functionality - Accept all / reject all consent flow - Consent persistence across reloads - Cookie FAB button reopens banner - Consent reset clears everything - API debug panel verification - Category toggles (necessary disabled) Total CMP test coverage: 5 spec files, ~100 test cases. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,235 @@
|
||||
import { test, expect } from '@playwright/test'
|
||||
import { navigateToSDK, waitForPageLoad } from '../utils/test-helpers'
|
||||
|
||||
/**
|
||||
* CMP Dashboard E2E Tests
|
||||
*
|
||||
* Tests the Consent Management Platform overview page (/sdk/cmp):
|
||||
* - Page load and header
|
||||
* - KPI cards (4 cards)
|
||||
* - Site selector dropdown
|
||||
* - Module navigation grid (8 modules)
|
||||
* - Module click navigation
|
||||
* - Compliance checklist items
|
||||
* - Cookie category acceptance bars
|
||||
*/
|
||||
|
||||
test.describe('CMP Dashboard — Page Load', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await navigateToSDK(page, '/cmp')
|
||||
})
|
||||
|
||||
test('should load without errors', async ({ page }) => {
|
||||
await expect(page.getByRole('heading', { name: 'Consent Management Platform' })).toBeVisible({
|
||||
timeout: 10000,
|
||||
})
|
||||
})
|
||||
|
||||
test('should display subtitle text', async ({ page }) => {
|
||||
await expect(page.getByText('Einwilligungen, Betroffenenrechte und Vendor-Compliance')).toBeVisible()
|
||||
})
|
||||
|
||||
test('should have "Banner testen" link to preview', async ({ page }) => {
|
||||
const link = page.locator('a[href="/sdk/cookie-banner/preview"]', { hasText: 'Banner testen' })
|
||||
await expect(link).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
test.describe('CMP Dashboard — KPI Cards', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await navigateToSDK(page, '/cmp')
|
||||
})
|
||||
|
||||
test('should display 4 KPI cards', async ({ page }) => {
|
||||
await page.waitForTimeout(1000)
|
||||
|
||||
await expect(page.getByText('Consents gesamt')).toBeVisible()
|
||||
await expect(page.getByText('Aktive Einwilligungen')).toBeVisible()
|
||||
await expect(page.getByText('Offene DSR-Anfragen')).toBeVisible()
|
||||
await expect(page.getByText('Konfigurierte Sites')).toBeVisible()
|
||||
})
|
||||
|
||||
test('should show numeric values in KPI cards (not loading forever)', async ({ page }) => {
|
||||
// Wait for loading to finish (values should not be "..." after 5s)
|
||||
await page.waitForTimeout(5000)
|
||||
|
||||
const kpiContainer = page.locator('.grid.grid-cols-2.md\\:grid-cols-4')
|
||||
await expect(kpiContainer).toBeVisible()
|
||||
|
||||
// At least one card should have a numeric value (not "...")
|
||||
const cardTexts = await kpiContainer.textContent()
|
||||
expect(cardTexts).toBeTruthy()
|
||||
// After loading, "..." should be replaced by actual numbers
|
||||
const hasNumber = /\d/.test(cardTexts || '')
|
||||
expect(hasNumber).toBeTruthy()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
test.describe('CMP Dashboard — Site Selector', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await navigateToSDK(page, '/cmp')
|
||||
await page.waitForTimeout(2000)
|
||||
})
|
||||
|
||||
test('should show site selector if sites exist', async ({ page }) => {
|
||||
// The site selector is a <select> element — may not be visible if no sites
|
||||
const selector = page.locator('select')
|
||||
const selectorVisible = await selector.isVisible().catch(() => false)
|
||||
|
||||
if (selectorVisible) {
|
||||
// Should have at least one option
|
||||
const optionCount = await selector.locator('option').count()
|
||||
expect(optionCount).toBeGreaterThan(0)
|
||||
} else {
|
||||
// No sites configured — that's OK for this test environment
|
||||
expect(true).toBeTruthy()
|
||||
}
|
||||
})
|
||||
|
||||
test('should change selected site when dropdown value changes', async ({ page }) => {
|
||||
const selector = page.locator('select')
|
||||
const selectorVisible = await selector.isVisible().catch(() => false)
|
||||
|
||||
if (selectorVisible) {
|
||||
const options = selector.locator('option')
|
||||
const count = await options.count()
|
||||
if (count > 1) {
|
||||
const secondValue = await options.nth(1).getAttribute('value')
|
||||
if (secondValue) {
|
||||
await selector.selectOption(secondValue)
|
||||
// Wait for stats to reload
|
||||
await page.waitForTimeout(1000)
|
||||
// Verify the dropdown now shows the second value
|
||||
await expect(selector).toHaveValue(secondValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
test.describe('CMP Dashboard — Module Navigation Grid', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await navigateToSDK(page, '/cmp')
|
||||
await page.waitForTimeout(1000)
|
||||
})
|
||||
|
||||
test('should display "CMP Module" section header', async ({ page }) => {
|
||||
await expect(page.getByText('CMP Module')).toBeVisible()
|
||||
})
|
||||
|
||||
test('should show 8 module cards', async ({ page }) => {
|
||||
const expectedModules = [
|
||||
'Cookie-Banner',
|
||||
'Live-Vorschau',
|
||||
'Consent-Records',
|
||||
'Consent-Verwaltung',
|
||||
'Vendor-Compliance',
|
||||
'DSR Portal',
|
||||
'Loeschfristen',
|
||||
'E-Mail-Templates',
|
||||
]
|
||||
|
||||
for (const label of expectedModules) {
|
||||
await expect(page.getByText(label, { exact: false }).first()).toBeVisible()
|
||||
}
|
||||
})
|
||||
|
||||
test('should navigate to Cookie-Banner when module is clicked', async ({ page }) => {
|
||||
const cookieBannerLink = page.locator('a[href="/sdk/cookie-banner"]').first()
|
||||
await expect(cookieBannerLink).toBeVisible()
|
||||
await cookieBannerLink.click()
|
||||
await waitForPageLoad(page)
|
||||
await expect(page).toHaveURL(/\/sdk\/cookie-banner/)
|
||||
})
|
||||
|
||||
test('should navigate to DSR Portal when module is clicked', async ({ page }) => {
|
||||
const dsrLink = page.locator('a[href="/sdk/dsr"]')
|
||||
await expect(dsrLink).toBeVisible()
|
||||
await dsrLink.click()
|
||||
await waitForPageLoad(page)
|
||||
await expect(page).toHaveURL(/\/sdk\/dsr/)
|
||||
})
|
||||
|
||||
test('should navigate to Live-Vorschau when module is clicked', async ({ page }) => {
|
||||
const previewLink = page.locator('a[href="/sdk/cookie-banner/preview"]').first()
|
||||
await expect(previewLink).toBeVisible()
|
||||
await previewLink.click()
|
||||
await waitForPageLoad(page)
|
||||
await expect(page).toHaveURL(/\/sdk\/cookie-banner\/preview/)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
test.describe('CMP Dashboard — Compliance Checklist', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await navigateToSDK(page, '/cmp')
|
||||
await page.waitForTimeout(1000)
|
||||
})
|
||||
|
||||
test('should display Compliance-Status section', async ({ page }) => {
|
||||
await expect(page.getByText('Compliance-Status')).toBeVisible()
|
||||
})
|
||||
|
||||
test('should show DSGVO requirement checklist items', async ({ page }) => {
|
||||
const items = [
|
||||
'Cookie-Banner konfiguriert',
|
||||
'Datenschutzerklaerung erstellt',
|
||||
'Impressum verlinkt',
|
||||
'Consent-Nachweis (Art. 7)',
|
||||
'DSR-Prozess eingerichtet',
|
||||
'Loeschfristen definiert',
|
||||
'Vendor-AVV vorhanden',
|
||||
'E-Mail-Templates aktiv',
|
||||
'EWR-Only Modus verfuegbar',
|
||||
]
|
||||
|
||||
for (const item of items) {
|
||||
await expect(page.getByText(item)).toBeVisible()
|
||||
}
|
||||
})
|
||||
|
||||
test('checklist items should be clickable links', async ({ page }) => {
|
||||
// Each checklist item is a link — verify at least one navigates correctly
|
||||
const bannerCheckLink = page.locator('a[href="/sdk/cookie-banner"]', {
|
||||
hasText: 'Cookie-Banner konfiguriert',
|
||||
})
|
||||
await expect(bannerCheckLink).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
test.describe('CMP Dashboard — Cookie Category Acceptance', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await navigateToSDK(page, '/cmp')
|
||||
await page.waitForTimeout(2000)
|
||||
})
|
||||
|
||||
test('should display category acceptance section', async ({ page }) => {
|
||||
await expect(page.getByText('Cookie-Kategorie Akzeptanz')).toBeVisible()
|
||||
})
|
||||
|
||||
test('should show acceptance bars or empty state', async ({ page }) => {
|
||||
// Either bars with category names or the empty state message
|
||||
const hasData = await page.getByText('necessary').isVisible().catch(() => false) ||
|
||||
await page.getByText('statistics').isVisible().catch(() => false)
|
||||
const hasEmptyState = await page.getByText('Noch keine Consent-Daten vorhanden').isVisible().catch(() => false)
|
||||
|
||||
expect(hasData || hasEmptyState).toBeTruthy()
|
||||
})
|
||||
|
||||
test('should show DSR breakdown section', async ({ page }) => {
|
||||
await expect(page.getByText('Betroffenenrechte (DSR)')).toBeVisible()
|
||||
// Either DSR stats or empty state
|
||||
const hasStats = await page.getByText('Gesamt').isVisible().catch(() => false)
|
||||
const hasEmpty = await page.getByText('Keine DSR-Anfragen vorhanden').isVisible().catch(() => false)
|
||||
expect(hasStats || hasEmpty).toBeTruthy()
|
||||
})
|
||||
|
||||
test('should have "Alle anzeigen" link to DSR page', async ({ page }) => {
|
||||
const link = page.locator('a[href="/sdk/dsr"]', { hasText: 'Alle anzeigen' })
|
||||
await expect(link).toBeVisible()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user