169 lines
6.9 KiB
TypeScript
169 lines
6.9 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
||
|
||
const BASE_URL = process.env.BASE_URL || process.env.FRONTEND_URL || 'http://frontend:3000';
|
||
|
||
const ADMIN_USERNAME = 'admin';
|
||
const ADMIN_PASSWORD = 'admin123';
|
||
|
||
test.describe('Role Editor', () => {
|
||
test('admin cannot edit admin role, can edit guest role, can create and delete temp-tester role', async ({ page }) => {
|
||
// Step 1: Login
|
||
console.log('🔐 Logging in...');
|
||
await page.goto(`${BASE_URL}/login`);
|
||
await page.waitForLoadState('networkidle');
|
||
|
||
await page.fill('input[type="text"], input[name="username"]', ADMIN_USERNAME);
|
||
await page.fill('input[type="password"], input[name="password"]', ADMIN_PASSWORD);
|
||
await page.click('button[type="submit"], button:has-text("Sign in")');
|
||
|
||
// Wait for navigation
|
||
await page.waitForURL(`${BASE_URL}/**`, { timeout: 10000 });
|
||
await page.waitForLoadState('networkidle');
|
||
console.log('✅ Logged in');
|
||
|
||
// Step 2: Navigate to Roles
|
||
console.log('🔐 Navigating to Roles...');
|
||
await page.click('a:has-text("🔐 Roles")');
|
||
await page.waitForLoadState('networkidle');
|
||
|
||
// Wait for role list to load
|
||
await page.waitForSelector('.role-editor-page', { timeout: 10000 });
|
||
|
||
// Step 3: Check admin and guest roles exist
|
||
console.log('👀 Checking admin and guest roles exist...');
|
||
const roleElements = await page.locator('.role-editor-page div[style*="border"] strong').allTextContents();
|
||
console.log('Roles found:', roleElements);
|
||
|
||
const hasAdmin = roleElements.some(r => r.toLowerCase().includes('admin'));
|
||
const hasGuest = roleElements.some(r => r.toLowerCase().includes('guest'));
|
||
expect(hasAdmin).toBe(true);
|
||
expect(hasGuest).toBe(true);
|
||
console.log('✅ admin and guest roles exist');
|
||
|
||
// Step 4: Click on guest role first (simpler test)
|
||
console.log('🔧 Clicking guest role...');
|
||
await page.click('.role-editor-page >> text=guest');
|
||
await page.waitForTimeout(1500);
|
||
|
||
// Wait for permission checkboxes to load
|
||
await page.waitForSelector('input[type="checkbox"]', { timeout: 5000 });
|
||
console.log('Permission checkboxes loaded');
|
||
|
||
// Try to save guest role (without changes first to verify save works)
|
||
console.log('💾 Trying to save guest role...');
|
||
const saveBtn1 = page.locator('button:has-text("Save Changes")');
|
||
await saveBtn1.scrollIntoViewIfNeeded();
|
||
await saveBtn1.click({ force: true });
|
||
await page.waitForTimeout(1000);
|
||
|
||
// Check for success message
|
||
const successMsg1 = await page.locator('text=Saved successfully').first().isVisible().catch(() => false);
|
||
console.log('Success message shown:', successMsg1);
|
||
expect(successMsg1).toBe(true);
|
||
console.log('✅ Can modify guest role verified');
|
||
|
||
// Step 5: Navigate to Roles again
|
||
console.log('🔐 Navigating to Roles again...');
|
||
await page.click('a:has-text("🔐 Roles")');
|
||
await page.waitForLoadState('networkidle');
|
||
await page.waitForSelector('.role-editor-page', { timeout: 10000 });
|
||
|
||
// Step 9: Check if temp-tester role exists, if not create it
|
||
console.log('🔍 Checking for temp-tester role...');
|
||
const allRoles = await page.locator('.role-editor-page >> text=temp-tester').count();
|
||
|
||
if (allRoles > 0) {
|
||
console.log('✅ temp-tester role already exists');
|
||
} else {
|
||
console.log('➕ Creating temp-tester role...');
|
||
await page.click('button:has-text("+ Create New Role")');
|
||
await page.waitForSelector('input[placeholder="e.g., developer, manager"]', { timeout: 5000 });
|
||
|
||
await page.fill('input[placeholder="e.g., developer, manager"]', 'temp-tester');
|
||
await page.fill('input[placeholder="Role description"]', 'Temporary tester role');
|
||
await page.click('button:has-text("Create")');
|
||
|
||
await page.waitForTimeout(1000);
|
||
|
||
// Verify role was created
|
||
const newRolesCount = await page.locator('.role-editor-page >> text=temp-tester').count();
|
||
expect(newRolesCount).toBeGreaterThan(0);
|
||
console.log('✅ temp-tester role created');
|
||
}
|
||
|
||
// Step 10: Navigate to Roles and verify temp-tester exists
|
||
console.log('🔐 Final verification - navigating to Roles...');
|
||
await page.click('a:has-text("🔐 Roles")');
|
||
await page.waitForLoadState('networkidle');
|
||
await page.waitForSelector('.role-editor-page', { timeout: 10000 });
|
||
|
||
const finalRolesCount = await page.locator('.role-editor-page >> text=temp-tester').count();
|
||
expect(finalRolesCount).toBeGreaterThan(0);
|
||
console.log('✅ temp-tester role exists verified');
|
||
|
||
// Step 11: Delete the temp-tester role and verify
|
||
console.log('🗑️ Deleting temp-tester role...');
|
||
|
||
// Navigate to Roles page fresh
|
||
await page.goto(`${BASE_URL}/roles`);
|
||
await page.waitForLoadState('networkidle');
|
||
await page.waitForTimeout(1500);
|
||
|
||
// Click on temp-tester role to select it
|
||
await page.click('.role-editor-page >> text=temp-tester');
|
||
await page.waitForTimeout(1500);
|
||
|
||
// Wait for permission checkboxes to load
|
||
await page.waitForSelector('input[type="checkbox"]', { timeout: 5000 }).catch(() => {});
|
||
await page.waitForTimeout(500);
|
||
|
||
// Scroll to make delete button visible
|
||
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
|
||
await page.waitForTimeout(500);
|
||
|
||
// Check if delete button is visible
|
||
const deleteBtn = page.locator('button:has-text("Delete Role")');
|
||
const deleteBtnVisible = await deleteBtn.isVisible().catch(() => false);
|
||
console.log('Delete button visible:', deleteBtnVisible);
|
||
|
||
if (deleteBtnVisible) {
|
||
// Set up dialog handler BEFORE clicking delete
|
||
page.on('dialog', async dialog => {
|
||
console.log('Dialog message:', dialog.message());
|
||
await dialog.accept();
|
||
});
|
||
|
||
// Click delete button
|
||
await deleteBtn.click();
|
||
|
||
// Wait for the delete to complete
|
||
await page.waitForTimeout(3000);
|
||
} else {
|
||
console.log('Delete button not visible - role might be protected');
|
||
}
|
||
|
||
// Navigate away and back to refresh
|
||
await page.goto(`${BASE_URL}/projects`);
|
||
await page.waitForTimeout(1000);
|
||
await page.goto(`${BASE_URL}/roles`);
|
||
await page.waitForLoadState('networkidle');
|
||
await page.waitForTimeout(1500);
|
||
|
||
// Verify temp-tester is no longer in the list
|
||
const roleCards = await page.locator('.role-editor-page div[style*="border"]').all();
|
||
let tempTesterFound = false;
|
||
for (const card of roleCards) {
|
||
const cardText = await card.textContent();
|
||
if (cardText && cardText.toLowerCase().includes('temp-tester')) {
|
||
tempTesterFound = true;
|
||
break;
|
||
}
|
||
}
|
||
console.log('temp-tester found after delete:', tempTesterFound);
|
||
expect(tempTesterFound).toBe(false);
|
||
console.log('✅ temp-tester role deleted and verified');
|
||
|
||
console.log('🎉 All role editor tests passed!');
|
||
});
|
||
});
|