pruebas e2e

This commit is contained in:
2025-12-23 11:36:48 -03:00
parent f695ed7213
commit c2d73b97db
30 changed files with 252 additions and 19 deletions
-13
View File
@@ -1,13 +0,0 @@
target/
.git/
node_modules/
.next/
web/studio/node_modules/
web/experience/node_modules/
web/studio/.next/
web/experience/.next/
services/*/target/
*.log
.env
.DS_Store
.vscode/
View File
View File
+11
View File
@@ -62,7 +62,12 @@ docker compose up -d --build
- **Rendimiento Bajo (Orange)**: P% to P+9%
- **Rendimiento Medio (Yellow)**: P+10% to P+15%
- **Buen Rendimiento (Green)**: P+16% to 90%
- **Buen Rendimiento (Green)**: P+16% to 90%
- **Excelente (Blue)**: 91%+
- **Automated Certificate Generation**:
- HTML-based customizable certificate templates
- Automatic download button upon passing a course
- PDF generation for print/save
### 📈 Analytics & Insights
- **Instructor Analytics Dashboard**:
@@ -85,6 +90,10 @@ docker compose up -d --build
- **Students**: Course enrollment, lesson consumption, progress tracking
- **Service-to-Service Authorization**: Secure internal API calls with token validation
- **Audit Logging**: All CMS mutations recorded for compliance and debugging
- **Admin Audit Dashboard**:
- Visual interface to view system logs
- Diff viewer for JSON changes
- Advanced filtering by user and action
### 🚀 Service Integration
- **Automatic Sync**: One-click publish from CMS to LMS
@@ -218,6 +227,8 @@ openccb/
-**Dynamic Passing Thresholds**: Customizable pass marks with 5-tier performance visualization
-**Role-Based Access Control**: Admin, Instructor, and Student roles with granular permissions
-**Enhanced Progress Dashboard**: Real-time weighted grades and visual performance bars
-**Certificate System**: Custom HTML templates and automated generation
-**Quality Assurance**: Automated End-to-End (E2E) testing pipeline with Playwright
## Contributing
View File
View File
+14
View File
@@ -52,6 +52,20 @@ services:
environment:
NEXT_PUBLIC_LMS_API_URL: http://localhost:3002
e2e:
build:
context: ./e2e
environment:
- STUDIO_URL=http://studio:3000
- EXPERIENCE_URL=http://experience:3003
depends_on:
- studio
- experience
volumes:
- ./e2e/tests:/e2e/tests
- ./e2e/playwright-report:/e2e/playwright-report
profiles: [ "test" ]
volumes:
postgres_data:
uploads_data:
+11
View File
@@ -0,0 +1,11 @@
FROM mcr.microsoft.com/playwright:v1.40.0-jammy
WORKDIR /e2e
COPY package*.json ./
RUN npm install
COPY . .
# Default command, can be overridden
CMD ["npx", "playwright", "test"]
+14
View File
@@ -0,0 +1,14 @@
{
"name": "openccb-e2e",
"version": "1.0.0",
"scripts": {
"test": "playwright test",
"test:ui": "playwright test --ui",
"test:debug": "playwright test --debug"
},
"devDependencies": {
"@playwright/test": "1.40.0",
"@types/node": "^20.10.0",
"typescript": "^5.3.0"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

File diff suppressed because one or more lines are too long
+44
View File
@@ -0,0 +1,44 @@
import { defineConfig, devices } from '@playwright/test';
// Use environment variables for base URLs, with fallbacks for local dev vs docker
const STUDIO_URL = process.env.STUDIO_URL || 'http://studio:3000';
const EXPERIENCE_URL = process.env.EXPERIENCE_URL || 'http://experience:3003';
export default defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,
reporter: 'html',
use: {
trace: 'on-first-retry',
screenshot: 'only-on-failure',
video: 'retain-on-failure',
},
projects: [
{
name: 'setup',
testMatch: /global\.setup\.ts/,
},
{
name: 'studio',
use: {
...devices['Desktop Chrome'],
baseURL: STUDIO_URL,
},
testMatch: /.*instructor.*\.spec\.ts/,
dependencies: ['setup'],
},
{
name: 'experience',
use: {
...devices['Desktop Chrome'],
baseURL: EXPERIENCE_URL,
},
testMatch: /.*student.*\.spec\.ts/,
dependencies: ['setup'],
},
],
});
+8
View File
@@ -0,0 +1,8 @@
import { test as setup } from '@playwright/test';
setup('check services are up', async ({ request }) => {
// We could ping health endpoints here
// const studio = await request.get('http://studio:3000');
// expect(studio.ok()).toBeTruthy();
console.log('Setup complete - proceeding to tests');
});
+49
View File
@@ -0,0 +1,49 @@
import { test, expect } from '@playwright/test';
test.describe('Instructor Flow', () => {
test('should login, create course, add content, and publish', async ({ page }) => {
const email = `instructor_${Date.now()}@test.com`;
// 0. Register (since DB might be empty)
await page.goto('/auth/register');
await page.fill('[placeholder="Instructor Name"]', 'E2E Instructor');
await page.fill('[placeholder="instructor@openccb.com"]', email); // or input[type="email"]
await page.fill('[placeholder="••••••••"]', 'password123'); // or input[type="password"]
await page.click('button[type="submit"]');
// Wait for navigation - Register automatically logs in and redirects to /
// Increase timeout for cold starts in CI/Docker
await expect(page).toHaveURL('/', { timeout: 15000 });
// Verify dashboard loaded
await expect(page.locator('h2')).toContainText('My Courses', { timeout: 10000 });
// 2. Create Course
// Usamos manejador de dialogo para el prompt
const courseName = 'Playwright E2E Course ' + Date.now();
page.on('dialog', dialog => dialog.accept(courseName));
await page.click('button:has-text("New Course")');
// Esperar a que aparezca el nuevo curso y hacer clic
await page.waitForTimeout(1000); // Wait for API
await page.click('text=Playwright E2E Course');
// 3. Add Module
await page.click('button:has-text("Add Module")');
await page.fill('[placeholder="Module Title"]', 'Module 1: Basics');
await page.click('button:has-text("Create Module")');
// 4. Add Lesson
await page.click('button:has-text("Add Lesson")');
await page.fill('[placeholder="Lesson Title"]', 'Intro Lesson');
// Select video type (assuming it's default or select dropdown)
await page.click('button:has-text("Create Lesson")');
// 5. Publish
await page.click('button:has-text("Publish Course")');
// Confirm publish
// Assuming there is a confirmation or toast
// await expect(page.locator('text=Published successfully')).toBeVisible();
});
});
+33
View File
@@ -0,0 +1,33 @@
import { test, expect } from '@playwright/test';
test.describe('Student Flow', () => {
test('should login and view catalog', async ({ page }) => {
// 1. Register/Login
// For simplicity, we assume registration or reuse existing
await page.goto('/auth/login');
// Register link?
// await page.click('text=Sign up');
// ... fill registration ...
// OR just login if we seed the DB.
// For E2E on fresh DB, we might need to register first.
// Let's try to register a new user every time to be safe
// Let's try to register a new user every time to be safe
const email = `student_${Date.now()}@test.com`;
await page.goto('/auth/register');
await page.fill('[placeholder="John Doe"]', 'Test Student');
await page.fill('[placeholder="name@company.com"]', email);
await page.fill('[placeholder="••••••••"]', 'password123');
await page.click('button[type="submit"]');
// Should redirect to dashboard/catalog
await expect(page).toHaveURL('/', { timeout: 15000 });
await expect(page.locator('h1')).toContainText('Available Courses', { timeout: 10000 });
// Check if the course from instructor flow is visible (might need refresh)
await page.reload();
// await expect(page.locator('text=Playwright E2E Course')).toBeVisible();
});
});
+6 -6
View File
@@ -32,7 +32,7 @@
- [x] Role-specific permissions and UI
- [x] Token-based authorization for protected endpoints
- [x] **Audit Logging**: All CMS mutations tracked
- [ ] **Audit UI**: Admin interface to view audit logs
- [x] **Audit UI**: Admin interface to view audit logs
## Phase 4: LMS Experience & Grading ✅
- [x] **Student Portal (Experience)**:
@@ -55,7 +55,7 @@
- [x] Configurable passing percentage per course
- [x] 5-tier performance visualization
- [x] Color-coded feedback (Reprobado to Excelente)
- [ ] **Certificates**: Automated certificate generation upon completion
- [x] **Certificates**: Automated certificate generation upon completion
## Phase 5: Analytics & Insights ✅
- [x] **Instructor Analytics Dashboard**:
@@ -122,7 +122,7 @@
- ✅ Enhanced student progress dashboard
**Next Priorities**:
1. Automated certificate generation
2. Audit log UI for administrators
3. Multi-tenancy support
4. AI-powered content generation
1. Multi-tenancy support
2. AI-powered content generation
3. Gamification (Badges & Achievements)
4. Advanced analytics & reporting
View File