# ๐Ÿ” Browser DevTools Verification Script ## For StudentProfileBuilderCreatePage - Complete Attribute Verification **Date:** 2025-01-20 **Component:** `StudentProfileBuilderCreatePage.jsx` **Route:** `/student/profile-builder` --- ## ๐Ÿ“‹ **VERIFICATION INSTRUCTIONS** ### **Step 1: Open Application** 1. Start your development server 2. Navigate to `http://localhost:3983/student/profile-builder` (or your local URL) 3. Log in as a student user 4. Open Browser DevTools (F12) ### **Step 2: Run Verification Script** Copy and paste the following script into the **Console** tab of DevTools: ```javascript // ============================================ // PROFILE EDITOR ATTRIBUTE VERIFICATION SCRIPT // ============================================ console.log('%c๐Ÿ” PROFILE EDITOR ATTRIBUTE VERIFICATION', 'color: #3b82f6; font-size: 16px; font-weight: bold;'); console.log('='.repeat(60)); // Helper function to check attribute function checkAttribute(testId, description) { const element = document.querySelector(`[data-testid="${testId}"]`); if (element) { console.log(`โœ… ${testId.padEnd(50)} - ${description}`); return { found: true, testId, description }; } else { console.log(`โŒ ${testId.padEnd(50)} - ${description} - MISSING`); return { found: false, testId, description }; } } // Helper function to count elements with pattern function countByPattern(pattern) { const elements = document.querySelectorAll(`[data-testid^="${pattern}"]`); return elements.length; } const results = { found: [], missing: [], total: 0 }; // ============================================ // PAGE-LEVEL ELEMENTS // ============================================ console.log('\n%c๐Ÿ“„ PAGE-LEVEL ELEMENTS', 'color: #10b981; font-weight: bold;'); results.total += 3; results.found.push(checkAttribute('profile_editor__page', 'Main page container')); results.found.push(checkAttribute('profile_editor__back_button', 'Back button')); results.found.push(checkAttribute('profile_editor__progress_value', 'Progress percentage')); // ============================================ // TAB NAVIGATION // ============================================ console.log('\n%c๐Ÿ“‘ TAB NAVIGATION', 'color: #10b981; font-weight: bold;'); const tabPatterns = [ 'profile_editor__tab_personal_information', 'profile_editor__tab_contact_information', 'profile_editor__tab_parent_guardian_information', 'profile_editor__tab_institution_details', 'profile_editor__tab_focus_areas', 'profile_editor__tab_self_assessment', 'profile_editor__tab_hobbies_clubs', 'profile_editor__tab_achievements', 'profile_editor__tab_expectations' ]; tabPatterns.forEach(pattern => { results.total++; const found = document.querySelector(`[data-testid="${pattern}"]`); if (found) { console.log(`โœ… ${pattern.padEnd(50)} - Tab button`); results.found.push({ found: true, testId: pattern }); } else { console.log(`โŒ ${pattern.padEnd(50)} - Tab button - MISSING`); results.missing.push({ found: false, testId: pattern }); } }); results.total += 3; results.found.push(checkAttribute('profile_editor__tabs_container', 'Tabs container')); results.found.push(checkAttribute('profile_editor__tabs_scroll_left_button', 'Scroll left button')); results.found.push(checkAttribute('profile_editor__tabs_scroll_right_button', 'Scroll right button')); // ============================================ // FORM ELEMENTS // ============================================ console.log('\n%c๐Ÿ“ FORM ELEMENTS', 'color: #10b981; font-weight: bold;'); results.total++; results.found.push(checkAttribute('profile_editor__form', 'Form container')); // ============================================ // PERSONAL INFORMATION // ============================================ console.log('\n%c๐Ÿ‘ค PERSONAL INFORMATION', 'color: #10b981; font-weight: bold;'); const personalInfoFields = [ { testId: 'profile_editor__first_name_input', desc: 'First Name' }, { testId: 'profile_editor__last_name_input', desc: 'Last Name' }, { testId: 'profile_editor__gender_select', desc: 'Gender' }, { testId: 'profile_editor__dob_input', desc: 'Date of Birth' }, { testId: 'profile_editor__age_input', desc: 'Age' }, { testId: 'profile_editor__nationality_input', desc: 'Nationality' }, { testId: 'profile_editor__language_input', desc: 'Language' }, { testId: 'profile_editor__student_id_input', desc: 'Student ID' }, { testId: 'profile_editor__student_cpid_input', desc: 'Student CPID' }, { testId: 'profile_editor__specially_abled_checkbox', desc: 'Specially Abled checkbox' }, { testId: 'profile_editor__specially_abled_details_textarea', desc: 'Specially Abled details' } ]; personalInfoFields.forEach(field => { results.total++; const result = checkAttribute(field.testId, field.desc); if (!result.found) results.missing.push(result); }); // ============================================ // CONTACT INFORMATION // ============================================ console.log('\n%c๐Ÿ“ง CONTACT INFORMATION', 'color: #10b981; font-weight: bold;'); const contactFields = [ { testId: 'profile_editor__email_input', desc: 'Email' }, { testId: 'profile_editor__phone_input', desc: 'Phone' }, { testId: 'profile_editor__address_input', desc: 'Address' }, { testId: 'profile_editor__city_input', desc: 'City' }, { testId: 'profile_editor__state_input', desc: 'State' }, { testId: 'profile_editor__zip_code_input', desc: 'ZIP Code' }, { testId: 'profile_editor__native_state_input', desc: 'Native State' } ]; contactFields.forEach(field => { results.total++; const result = checkAttribute(field.testId, field.desc); if (!result.found) results.missing.push(result); }); // ============================================ // PARENT/GUARDIAN INFORMATION // ============================================ console.log('\n%c๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง PARENT/GUARDIAN INFORMATION', 'color: #10b981; font-weight: bold;'); const parentFields = [ { testId: 'profile_editor__father_full_name_input', desc: 'Father Full Name' }, { testId: 'profile_editor__father_age_range_select', desc: 'Father Age Range' }, { testId: 'profile_editor__father_occupation_input', desc: 'Father Occupation' }, { testId: 'profile_editor__father_email_input', desc: 'Father Email' }, { testId: 'profile_editor__mother_full_name_input', desc: 'Mother Full Name' }, { testId: 'profile_editor__mother_age_range_select', desc: 'Mother Age Range' }, { testId: 'profile_editor__mother_occupation_input', desc: 'Mother Occupation' }, { testId: 'profile_editor__mother_email_input', desc: 'Mother Email' }, { testId: 'profile_editor__guardian_different_checkbox', desc: 'Guardian Different checkbox' }, { testId: 'profile_editor__guardian_full_name_input', desc: 'Guardian Full Name' }, { testId: 'profile_editor__guardian_relationship_input', desc: 'Guardian Relationship' }, { testId: 'profile_editor__guardian_phone_input', desc: 'Guardian Phone' }, { testId: 'profile_editor__guardian_email_input', desc: 'Guardian Email' }, { testId: 'profile_editor__guardian_address_input', desc: 'Guardian Address' } ]; parentFields.forEach(field => { results.total++; const result = checkAttribute(field.testId, field.desc); if (!result.found) results.missing.push(result); }); // ============================================ // EDUCATION DETAILS // ============================================ console.log('\n%c๐ŸŽ“ EDUCATION DETAILS', 'color: #10b981; font-weight: bold;'); const educationFields = [ { testId: 'profile_editor__current_grade_input', desc: 'Current Grade/Class' }, { testId: 'profile_editor__section_input', desc: 'Section' }, { testId: 'profile_editor__roll_number_input', desc: 'Roll Number' }, { testId: 'profile_editor__board_stream_select', desc: 'Board/Stream' } ]; educationFields.forEach(field => { results.total++; const result = checkAttribute(field.testId, field.desc); if (!result.found) results.missing.push(result); }); // ============================================ // FOCUS AREAS (Dynamic) // ============================================ console.log('\n%c๐ŸŽฏ FOCUS AREAS (Dynamic Attributes)', 'color: #10b981; font-weight: bold;'); const shortTermFocusCount = countByPattern('profile_editor__short_term_focus__'); const longTermFocusCount = countByPattern('profile_editor__long_term_focus__'); console.log(`Short-term Focus Areas: ${shortTermFocusCount} checkboxes found`); console.log(`Long-term Focus Areas: ${longTermFocusCount} checkboxes found`); results.total += 2; if (shortTermFocusCount > 0) { results.found.push({ found: true, testId: 'profile_editor__short_term_focus__*' }); } else { results.missing.push({ found: false, testId: 'profile_editor__short_term_focus__*' }); } if (longTermFocusCount > 0) { results.found.push({ found: true, testId: 'profile_editor__long_term_focus__*' }); } else { results.missing.push({ found: false, testId: 'profile_editor__long_term_focus__*' }); } results.total += 2; results.found.push(checkAttribute('profile_editor__short_term_focus_others_text', 'Short-term Focus Others')); results.found.push(checkAttribute('profile_editor__long_term_focus_others_text', 'Long-term Focus Others')); // ============================================ // SELF-ASSESSMENT (Dynamic) // ============================================ console.log('\n%c๐Ÿ’ช SELF-ASSESSMENT (Dynamic Attributes)', 'color: #10b981; font-weight: bold;'); const strengthCount = countByPattern('profile_editor__strength__'); const improvementCount = countByPattern('profile_editor__improvement__'); console.log(`Strengths: ${strengthCount} checkboxes found`); console.log(`Areas of Improvement: ${improvementCount} checkboxes found`); results.total += 2; if (strengthCount > 0) { results.found.push({ found: true, testId: 'profile_editor__strength__*' }); } else { results.missing.push({ found: false, testId: 'profile_editor__strength__*' }); } if (improvementCount > 0) { results.found.push({ found: true, testId: 'profile_editor__improvement__*' }); } else { results.missing.push({ found: false, testId: 'profile_editor__improvement__*' }); } results.total += 2; results.found.push(checkAttribute('profile_editor__strength_others_text', 'Strengths Others')); results.found.push(checkAttribute('profile_editor__improvement_others_text', 'Improvements Others')); // ============================================ // HOBBIES & CLUBS (Dynamic) // ============================================ console.log('\n%c๐ŸŽจ HOBBIES & CLUBS (Dynamic Attributes)', 'color: #10b981; font-weight: bold;'); const hobbyCount = countByPattern('profile_editor__hobby__'); const clubCount = countByPattern('profile_editor__club_'); console.log(`Hobbies: ${hobbyCount} checkboxes found`); console.log(`Clubs: ${clubCount} checkboxes found`); results.total += 2; if (hobbyCount > 0) { results.found.push({ found: true, testId: 'profile_editor__hobby__*' }); } else { results.missing.push({ found: false, testId: 'profile_editor__hobby__*' }); } if (clubCount > 0) { results.found.push({ found: true, testId: 'profile_editor__club_*' }); } else { results.missing.push({ found: false, testId: 'profile_editor__club_*' }); } results.total += 2; results.found.push(checkAttribute('profile_editor__hobby_other_text', 'Hobby Others')); results.found.push(checkAttribute('profile_editor__club_other_text', 'Club Others')); // ============================================ // ACHIEVEMENTS // ============================================ console.log('\n%c๐Ÿ† ACHIEVEMENTS', 'color: #10b981; font-weight: bold;'); const achievementFields = [ { testId: 'profile_editor__achievement_academics_textarea', desc: 'Academics' }, { testId: 'profile_editor__achievement_sports_textarea', desc: 'Sports' }, { testId: 'profile_editor__achievement_cultural_textarea', desc: 'Cultural' }, { testId: 'profile_editor__achievement_trained_textarea', desc: 'Trained' }, { testId: 'profile_editor__achievement_others_textarea', desc: 'Others' } ]; achievementFields.forEach(field => { results.total++; const result = checkAttribute(field.testId, field.desc); if (!result.found) results.missing.push(result); }); // ============================================ // EXPECTATIONS (Dynamic) // ============================================ console.log('\n%c๐ŸŒŸ EXPECTATIONS (Dynamic Attributes)', 'color: #10b981; font-weight: bold;'); const expectationCount = countByPattern('profile_editor__expectation__'); console.log(`Expectations: ${expectationCount} checkboxes found`); results.total++; if (expectationCount > 0) { results.found.push({ found: true, testId: 'profile_editor__expectation__*' }); } else { results.missing.push({ found: false, testId: 'profile_editor__expectation__*' }); } results.total++; results.found.push(checkAttribute('profile_editor__expectation_others_text', 'Expectations Others')); // ============================================ // NAVIGATION BUTTONS // ============================================ console.log('\n%c๐Ÿ”˜ NAVIGATION BUTTONS', 'color: #10b981; font-weight: bold;'); const navButtons = [ { testId: 'profile_editor__prev_button', desc: 'Previous' }, { testId: 'profile_editor__next_button', desc: 'Next' }, { testId: 'profile_editor__cancel_button', desc: 'Cancel' }, { testId: 'profile_editor__save_button', desc: 'Save' } ]; navButtons.forEach(button => { results.total++; const result = checkAttribute(button.testId, button.desc); if (!result.found) results.missing.push(result); }); // ============================================ // SUMMARY // ============================================ console.log('\n' + '='.repeat(60)); console.log('%c๐Ÿ“Š VERIFICATION SUMMARY', 'color: #3b82f6; font-size: 16px; font-weight: bold;'); console.log('='.repeat(60)); const foundCount = results.found.filter(r => r.found).length; const missingCount = results.missing.length; const completionRate = ((foundCount / results.total) * 100).toFixed(1); console.log(`\nTotal Attributes Checked: ${results.total}`); console.log(`โœ… Found: ${foundCount}`); console.log(`โŒ Missing: ${missingCount}`); console.log(`๐Ÿ“ˆ Completion Rate: ${completionRate}%`); if (missingCount === 0) { console.log('\n%c๐ŸŽ‰ ALL ATTRIBUTES VERIFIED! 100% COMPLETE!', 'color: #10b981; font-size: 14px; font-weight: bold;'); } else { console.log('\n%cโš ๏ธ SOME ATTRIBUTES MISSING - See details above', 'color: #f59e0b; font-size: 14px; font-weight: bold;'); console.log('\nMissing Attributes:'); results.missing.forEach(item => { console.log(` โŒ ${item.testId}`); }); } // Return results for further inspection return { total: results.total, found: foundCount, missing: missingCount, completionRate: `${completionRate}%`, missingAttributes: results.missing.map(m => m.testId) }; ``` --- ## ๐Ÿงช **TESTING DYNAMIC ATTRIBUTES** ### **Test 1: MultiSelectPicker Checkboxes** 1. **Navigate to Focus Areas tab** 2. Run in console: ```javascript // Check short-term focus areas const shortTerm = document.querySelectorAll('[data-testid^="profile_editor__short_term_focus__"]'); console.log(`Short-term Focus Areas: ${shortTerm.length} checkboxes`); shortTerm.forEach(cb => console.log(` - ${cb.getAttribute('data-testid')}`)); // Check long-term focus areas const longTerm = document.querySelectorAll('[data-testid^="profile_editor__long_term_focus__"]'); console.log(`Long-term Focus Areas: ${longTerm.length} checkboxes`); longTerm.forEach(cb => console.log(` - ${cb.getAttribute('data-testid')}`)); ``` 3. **Navigate to Self-Assessment tab** ```javascript // Check strengths const strengths = document.querySelectorAll('[data-testid^="profile_editor__strength__"]'); console.log(`Strengths: ${strengths.length} checkboxes`); strengths.forEach(cb => console.log(` - ${cb.getAttribute('data-testid')}`)); // Check improvements const improvements = document.querySelectorAll('[data-testid^="profile_editor__improvement__"]'); console.log(`Improvements: ${improvements.length} checkboxes`); improvements.forEach(cb => console.log(` - ${cb.getAttribute('data-testid')}`)); ``` 4. **Navigate to Hobbies & Clubs tab** ```javascript // Check hobbies const hobbies = document.querySelectorAll('[data-testid^="profile_editor__hobby__"]'); console.log(`Hobbies: ${hobbies.length} checkboxes`); hobbies.forEach(cb => console.log(` - ${cb.getAttribute('data-testid')}`)); // Check clubs const clubs = document.querySelectorAll('[data-testid^="profile_editor__club_"]'); console.log(`Clubs: ${clubs.length} checkboxes`); clubs.forEach(cb => console.log(` - ${cb.getAttribute('data-testid')}`)); ``` 5. **Navigate to Expectations tab** ```javascript // Check expectations const expectations = document.querySelectorAll('[data-testid^="profile_editor__expectation__"]'); console.log(`Expectations: ${expectations.length} checkboxes`); expectations.forEach(cb => console.log(` - ${cb.getAttribute('data-testid')}`)); ``` ### **Test 2: Tab Navigation** Run in console: ```javascript // Check all tab buttons const tabs = document.querySelectorAll('[data-testid^="profile_editor__tab_"]'); console.log(`Total Tabs: ${tabs.length}`); tabs.forEach(tab => { console.log(` - ${tab.getAttribute('data-testid')} - ${tab.textContent.trim()}`); }); ``` ### **Test 3: Dynamic "Others" Inputs** Test that "Others" inputs appear when corresponding options are selected: ```javascript // Test short-term focus "Others" input const shortTermOthers = document.querySelector('[data-testid="profile_editor__short_term_focus_others_text"]'); if (shortTermOthers) { console.log('โœ… Short-term Focus Others input found'); } else { console.log('โš ๏ธ Short-term Focus Others input not visible (may need to select "Others" option)'); } // Similar tests for other "Others" inputs const longTermOthers = document.querySelector('[data-testid="profile_editor__long_term_focus_others_text"]'); const strengthOthers = document.querySelector('[data-testid="profile_editor__strength_others_text"]'); const improvementOthers = document.querySelector('[data-testid="profile_editor__improvement_others_text"]'); const hobbyOthers = document.querySelector('[data-testid="profile_editor__hobby_other_text"]'); const clubOthers = document.querySelector('[data-testid="profile_editor__club_other_text"]'); const expectationOthers = document.querySelector('[data-testid="profile_editor__expectation_others_text"]'); ``` --- ## ๐Ÿ“ **EXPECTED RESULTS** ### **Static Attributes:** - **Total:** ~62 static attributes - **Expected:** All 62 should be found ### **Dynamic Attributes:** - **Short-term Focus Areas:** 10-20 checkboxes (depending on age category) - **Long-term Focus Areas:** 10-20 checkboxes - **Strengths:** 19 checkboxes - **Improvements:** 19 checkboxes - **Hobbies:** 12 checkboxes - **Clubs:** 12 checkboxes - **Expectations:** 10 checkboxes - **Tabs:** 9 tab buttons ### **Total Expected:** - **Static:** 62 attributes - **Dynamic:** 100+ checkboxes (varies by age category) - **Total:** 162+ attributes --- ## โœ… **VERIFICATION CHECKLIST** - [ ] All page-level attributes found - [ ] All tab navigation attributes found - [ ] All form field attributes found - [ ] All parent/guardian attributes found - [ ] All education attributes found - [ ] Dynamic MultiSelectPicker checkboxes have correct patterns - [ ] Dynamic club checkboxes have correct patterns - [ ] Dynamic tab buttons have correct patterns - [ ] "Others" inputs appear when corresponding options are selected - [ ] All navigation buttons found - [ ] Completion rate is 100% --- **Note:** Some attributes may only be visible when: - Specific tabs are active - Certain options are selected (e.g., "Others" inputs) - Conditional fields are shown (e.g., guardian fields when "Guardian is different" is checked) Make sure to test all tabs and interaction states!