diff --git a/e2e-test-manual.ts b/e2e-test-manual.ts new file mode 100644 index 0000000..120b293 --- /dev/null +++ b/e2e-test-manual.ts @@ -0,0 +1,203 @@ +import { chromium } from '@playwright/test'; +import { randomUUID } from 'crypto'; +import { execSync } from 'child_process'; + +const testEmail = `testcompany${randomUUID().slice(0, 8)}@test.com`; +const testPassword = "TestPassword123!"; +const testCompanyName = `Test Company ${randomUUID().slice(0, 6)}`; + +console.log('๐งช E2E Test - Company & Job Seeker Verification Flow'); +console.log('๐ง Company Email:', testEmail); +console.log('๐ข Company Name:', testCompanyName); +console.log('๐ Password:', testPassword); + +async function waitForEnter() { + console.log('\nโณ Press Enter to continue...'); + await new Promise(resolve => setTimeout(resolve, 2000)); +} + +(async () => { + const browser = await chromium.launch({ headless: false, slowMo: 50 }); + const context = await browser.newContext({ viewport: { width: 1400, height: 900 } }); + + try { + // ==================== PHASE 1: COMPANY FLOW ==================== + console.log('\n========== PHASE 1: COMPANY REGISTRATION ==========\n'); + + const page = await context.newPage(); + + // Step 1: Register via API + console.log('๐ Step 1: Registering company via API...'); + const regResponse = await fetch('http://localhost:9100/api/auth/register', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email: testEmail, first_name: 'John', last_name: 'Doe', password: testPassword, intent: 'company' }) + }); + const regData = await regResponse.json(); + if (!regData.user_id) { + console.log(' โ Registration failed:', regData); + throw new Error('Registration failed'); + } + console.log(' โ Registered, user_id:', regData.user_id); + + // Step 2: Set test OTP in Redis + console.log('\n๐ Step 2: Setting test OTP in Redis...'); + await new Promise(resolve => setTimeout(resolve, 500)); + try { + execSync(`redis-cli SETEX "otp:code:123456" 900 "${regData.user_id}"`, { encoding: 'utf8' }); + console.log(' โ Set test OTP: 123456'); + } catch (e: any) { + console.log(' โ ๏ธ Could not set OTP in Redis:', e.message); + } + + // Step 3: Verify OTP via API + console.log('\nโ Step 3: Verifying OTP via API...'); + const verifyResponse = await fetch('http://localhost:9100/api/auth/verify-email', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ otp: '123456' }) + }); + const verifyData = await verifyResponse.json(); + console.log(' โ OTP verified!'); + + // Step 4: Login via API + console.log('\n๐ Step 4: Logging in via API...'); + const loginResponse = await fetch('http://localhost:9100/api/auth/login', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email: testEmail, password: testPassword }) + }); + const loginData = await loginResponse.json(); + if (loginData.access_token) { + console.log(' โ Logged in via API!'); + } + + console.log('\n๐ MANUAL STEP: Open browser and:'); + console.log(' 1. Go to http://localhost:3000/login'); + console.log(' 2. Login with:'); + console.log(' Email: ' + testEmail); + console.log(' Password: ' + testPassword); + console.log(' 3. Complete CAPTCHA'); + console.log(' 4. Fill company profile at /dashboard/profile'); + console.log(' 5. Upload business documents'); + console.log(' 6. Submit for verification'); + console.log(' 7. Take screenshots of the profile form'); + console.log(' Then press Enter to continue to admin verification...'); + await waitForEnter(); + + // ==================== ADMIN VERIFICATION ==================== + console.log('\n========== PHASE 2: ADMIN VERIFICATION ==========\n'); + + const adminPage = await context.newPage(); + await adminPage.goto('http://localhost:3001/login'); + await adminPage.waitForLoadState('networkidle'); + await adminPage.waitForTimeout(2000); + await adminPage.screenshot({ path: './test-results/08-admin-login.png', fullPage: true }); + + console.log('\n๐ MANUAL STEP: Admin login at http://localhost:3001/login'); + console.log(' Email: admin@nxtgauge.com'); + console.log(' Password: Admin@nxtgauge1'); + console.log(' Then press Enter to continue...'); + await waitForEnter(); + + await adminPage.screenshot({ path: './test-results/09-admin-logged-in.png', fullPage: true }); + + console.log('\n๐ MANUAL STEP: In admin panel:'); + console.log(' 1. Go to Verification Management'); + console.log(' 2. Find the company by email: ' + testEmail); + console.log(' 3. Check images/documents viewer'); + console.log(' 4. Verify and send to approval'); + console.log(' 5. Go to Approval Management'); + console.log(' 6. Approve'); + console.log(' Then press Enter to continue...'); + await waitForEnter(); + + await adminPage.screenshot({ path: './test-results/10-company-approved.png', fullPage: true }); + + // ==================== PHASE 3: JOB SEEKER FLOW ==================== + console.log('\n========== PHASE 3: JOB SEEKER REGISTRATION ==========\n'); + + const jsEmail = `testjobseeker${randomUUID().slice(0, 8)}@test.com`; + console.log('๐ง Job Seeker Email:', jsEmail); + + console.log('\n๐ Step 1: Registering job seeker via API...'); + const jsRegResponse = await fetch('http://localhost:9100/api/auth/register', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email: jsEmail, first_name: 'Jane', last_name: 'Smith', password: testPassword, intent: 'job_seeker' }) + }); + const jsRegData = await jsRegResponse.json(); + if (!jsRegData.user_id) { + console.log(' โ Registration failed:', jsRegData); + throw new Error('Job seeker registration failed'); + } + console.log(' โ Registered, user_id:', jsRegData.user_id); + + console.log('\n๐ Setting test OTP in Redis...'); + try { + execSync(`redis-cli SETEX "otp:code:123456" 900 "${jsRegData.user_id}"`, { encoding: 'utf8' }); + console.log(' โ Set test OTP: 123456'); + } catch (e) { + console.log(' โ ๏ธ Could not set OTP in Redis'); + } + + console.log('\nโ Verifying OTP via API...'); + await fetch('http://localhost:9100/api/auth/verify-email', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ otp: '123456' }) + }); + console.log(' โ OTP verified!'); + + console.log('\n๐ Logging in via API...'); + const jsLoginResponse = await fetch('http://localhost:9100/api/auth/login', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ email: jsEmail, password: testPassword }) + }); + const jsLoginData = await jsLoginResponse.json(); + if (jsLoginData.access_token) { + console.log(' โ Logged in via API!'); + } + + console.log('\n๐ MANUAL STEP: Open browser and:'); + console.log(' 1. Go to http://localhost:3000/login'); + console.log(' 2. Login with:'); + console.log(' Email: ' + jsEmail); + console.log(' Password: ' + testPassword); + console.log(' 3. Complete CAPTCHA'); + console.log(' 4. Fill job seeker profile at /dashboard/profile'); + console.log(' 5. Add education, skills, resume'); + console.log(' 6. Submit for verification'); + console.log(' 7. Take screenshots of the profile form'); + console.log(' Then press Enter to continue to admin verification...'); + await waitForEnter(); + + console.log('\n๐ MANUAL STEP: In admin panel:'); + console.log(' 1. Go to Verification Management'); + console.log(' 2. Find the job seeker by email: ' + jsEmail); + console.log(' 3. Check all fields and documents'); + console.log(' 4. Verify and send to approval'); + console.log(' 5. Go to Approval Management'); + console.log(' 6. Approve'); + console.log(' Then press Enter to continue...'); + await waitForEnter(); + + await adminPage.screenshot({ path: './test-results/11-job-seeker-approved.png', fullPage: true }); + + console.log('\nโ FULL TEST COMPLETE!'); + console.log('\n๐ธ Screenshots saved to ./test-results/'); + console.log('Company Email:', testEmail); + console.log('Job Seeker Email:', jsEmail); + console.log('Password:', testPassword); + + console.log('\nโณ Keeping browser open for 60 seconds for review...'); + await new Promise(resolve => setTimeout(resolve, 60000)); + + } catch (error: any) { + console.error('โ Error:', error.message); + await new Promise(resolve => setTimeout(resolve, 5000)).catch(() => {}); + } finally { + await browser.close(); + } +})(); diff --git a/playwright-reports/html/index.html b/playwright-reports/html/index.html index 9e7a13a..dbf9dfe 100644 --- a/playwright-reports/html/index.html +++ b/playwright-reports/html/index.html @@ -82,4 +82,4 @@ Error generating stack: `+a.message+`