/** * E2E Tests for Moderation Lock Management * * Browser-based tests for lock UI and interactions * Uses authenticated state from global setup */ import { test, expect } from '@playwright/test'; // Configure test to use moderator auth state test.use({ storageState: '.auth/moderator.json' }); test.describe('Moderation Lock Management UI', () => { test.beforeEach(async ({ page }) => { // Navigate to moderation queue (already authenticated via storageState) await page.goto('/moderation/queue'); await page.waitForLoadState('networkidle'); }); test('moderator can see queue items', async ({ page }) => { // Wait for queue items to load const queueItems = page.locator('[data-testid="queue-item"]'); // Check if queue items are visible (may be 0 if queue is empty) const count = await queueItems.count(); expect(count).toBeGreaterThanOrEqual(0); }); test('moderator can claim pending submission', async ({ page }) => { // Wait for queue items to load await page.waitForSelector('[data-testid="queue-item"]', { timeout: 10000 }); // Find first pending item with claim button const firstItem = page.locator('[data-testid="queue-item"]').first(); const claimButton = firstItem.locator('button:has-text("Claim Submission")'); // Check if claim button exists const claimButtonCount = await claimButton.count(); if (claimButtonCount === 0) { console.log('No unclaimed submissions found - skipping test'); test.skip(); return; } // Verify button exists and is enabled await expect(claimButton).toBeVisible(); await expect(claimButton).toBeEnabled(); // Click claim await claimButton.click(); // Verify lock UI appears (claimed by you badge) await expect(firstItem.locator('text=/claimed by you/i')).toBeVisible({ timeout: 5000 }); // Verify approve/reject buttons are now enabled const approveButton = firstItem.locator('button:has-text("Approve")'); const rejectButton = firstItem.locator('button:has-text("Reject")'); await expect(approveButton).toBeEnabled(); await expect(rejectButton).toBeEnabled(); }); test('lock timer displays countdown', async ({ page }) => { await page.waitForSelector('[data-testid="queue-item"]', { timeout: 10000 }); const firstItem = page.locator('[data-testid="queue-item"]').first(); const claimButton = firstItem.locator('button:has-text("Claim Submission")'); const claimButtonCount = await claimButton.count(); if (claimButtonCount === 0) { test.skip(); return; } // Claim submission await claimButton.click(); await page.waitForTimeout(2000); // Look for lock status display with timer (format: 14:XX or 15:00) const lockStatus = page.locator('[data-testid="lock-status-display"]'); await expect(lockStatus).toBeVisible({ timeout: 5000 }); }); test('extend lock button appears when enabled', async ({ page }) => { await page.waitForSelector('[data-testid="queue-item"]', { timeout: 10000 }); const firstItem = page.locator('[data-testid="queue-item"]').first(); const claimButton = firstItem.locator('button:has-text("Claim Submission")'); const claimButtonCount = await claimButton.count(); if (claimButtonCount === 0) { test.skip(); return; } // Claim submission await claimButton.click(); await page.waitForTimeout(2000); // Check if extend button exists (may not appear immediately if > 5 minutes remain) const extendButton = page.locator('button:has-text("Extend Lock")'); const extendButtonCount = await extendButton.count(); // If button doesn't exist, that's expected behavior (> 5 minutes remaining) expect(extendButtonCount).toBeGreaterThanOrEqual(0); }); test('release lock button clears claim', async ({ page }) => { await page.waitForSelector('[data-testid="queue-item"]', { timeout: 10000 }); const firstItem = page.locator('[data-testid="queue-item"]').first(); const claimButton = firstItem.locator('button:has-text("Claim Submission")'); const claimButtonCount = await claimButton.count(); if (claimButtonCount === 0) { test.skip(); return; } // Claim submission await claimButton.click(); await page.waitForTimeout(2000); // Find and click release button const releaseButton = page.locator('button:has-text("Release Lock")'); await expect(releaseButton).toBeVisible({ timeout: 5000 }); await releaseButton.click(); // Verify claim button reappears await expect(claimButton).toBeVisible({ timeout: 5000 }); }); test('locked by another moderator shows warning', async ({ page }) => { // Check if any submission has the "Locked by Another Moderator" badge const lockedBadge = page.locator('text=/Locked by .*/i'); // If no locked submissions, this test is informational only const count = await lockedBadge.count(); expect(count).toBeGreaterThanOrEqual(0); }); });