5.5: Testing & Debugging
Master essential testing and debugging techniques to ensure your website works perfectly across all browsers and devices. Learn how to use browser DevTools, validate HTML/CSS, fix common issues, and test responsive designs.
1. Cross-Browser Testing
Different browsers render websites differently. Test on all major browsers.
Major Browsers to Test
Desktop browsers (priority order):
1. Google Chrome (65% market share)
2. Safari (15% - Mac/iOS users)
3. Microsoft Edge (10% - Windows default)
4. Firefox (5% - privacy-focused users)
5. Opera (2% - niche users)
Mobile browsers:
1. Chrome Mobile (Android default)
2. Safari Mobile (iOS only)
3. Samsung Internet (Samsung devices)
Common Browser Differences
CSS Grid support:
/* Modern browsers */
.gallery {
display: grid;
gap: 1rem;
}
/* Fallback for old browsers */
@supports not (display: grid) {
.gallery {
display: flex;
flex-wrap: wrap;
}
.gallery > * {
margin: 0.5rem;
}
}
Flexbox gap property:
/* Modern: gap property */
.nav {
display: flex;
gap: 2rem;
}
/* Fallback: margin */
.nav li {
margin-right: 2rem;
}
.nav li:last-child {
margin-right: 0;
}
Browser DevTools Shortcuts
Open DevTools:
Chrome/Edge: F12 or Ctrl+Shift+I (Cmd+Opt+I on Mac)
Firefox: F12 or Ctrl+Shift+I (Cmd+Opt+I on Mac)
Safari: Cmd+Opt+I (enable in Preferences first)
Key DevTools panels:
Elements - Inspect HTML/CSS
Console - JavaScript errors and logs
Network - File loading and performance
Performance - Page speed analysis
Application - Storage, cache, service workers
Lighthouse - Automated audits
Testing Browser Compatibility
Check feature support:
- Visit caniuse.com
- Search for CSS/JS feature
- See browser compatibility table
Example: CSS Grid support
Chrome: ✓ Version 57+
Firefox: ✓ Version 52+
Safari: ✓ Version 10.1+
Edge: ✓ Version 16+
IE 11: ✗ Not supported (provide fallback)
2. Responsive Testing
Test your site on multiple screen sizes and devices.
Common Screen Sizes
Mobile devices:
iPhone SE: 375 × 667 px (small)
iPhone 12/13: 390 × 844 px (standard)
iPhone 14 Pro: 393 × 852 px (standard)
Samsung S21: 360 × 800 px (standard)
Pixel 5: 393 × 851 px (standard)
Tablets:
iPad Mini: 768 × 1024 px
iPad Air: 820 × 1180 px
iPad Pro: 1024 × 1366 px
Samsung Tab: 800 × 1280 px
Desktop:
Laptop: 1366 × 768 px (most common)
Desktop: 1920 × 1080 px (Full HD)
Large desktop: 2560 × 1440 px (2K)
4K monitor: 3840 × 2160 px
Using Browser DevTools for Responsive Testing
Chrome DevTools Device Mode:
1. Open DevTools (F12)
2. Click device toolbar icon (Ctrl+Shift+M)
3. Select device from dropdown OR
4. Enter custom dimensions
5. Test portrait and landscape
6. Check touch interactions
Testing checklist per size:
Mobile (≤ 640px):
□ Navigation hamburger works
□ Text is readable (min 16px)
□ Buttons are tappable (min 44×44px)
□ No horizontal scrolling
□ Images scale properly
Tablet (641-1024px):
□ Layout adjusts appropriately
□ Navigation may expand or stay hamburger
□ Two-column layouts work
□ Touch targets adequate
Desktop (≥ 1025px):
□ Full navigation visible
□ Multi-column layouts
□ Hover states work
□ Content not too wide (max-width)
Responsive Design Testing Tools
Built-in browser tools:
- Chrome DevTools Device Mode
- Firefox Responsive Design Mode (Ctrl+Shift+M)
- Safari Responsive Design Mode
Online tools:
BrowserStack - Real device testing (paid)
LambdaTest - Cross-browser testing (free tier)
Responsively App - Desktop app for multi-device preview
Mobile testing:
Real devices: Best option (borrow phones/tablets)
Browser DevTools: Good approximation
BrowserStack: Cloud-based real devices
3. HTML Validation
Validate HTML to catch errors and ensure standards compliance.
W3C Markup Validator
Using the validator:
1. Go to https://validator.w3.org/
2. Choose input method:
- Validate by URL (for live sites)
- Validate by file upload
- Validate by direct input (paste code)
3. Click "Check"
4. Review errors and warnings
5. Fix issues in your code
6. Re-validate until no errors
Common HTML errors:
<!-- Error: Unclosed tags -->
<div>
<p>Some text
</div> ✗ Missing </p>
<!-- Fixed -->
<div>
<p>Some text</p>
</div> ✓
<!-- Error: Duplicate IDs -->
<div id="content">...</div>
<div id="content">...</div> ✗ ID must be unique
<!-- Fixed -->
<div id="content-1">...</div>
<div id="content-2">...</div> ✓
<!-- Error: Invalid nesting -->
<p>
<div>Text</div> ✗ Block element in inline element
</p>
<!-- Fixed -->
<div>
<p>Text</p> ✓
</div>
<!-- Error: Missing alt attribute -->
<img src="photo.jpg"> ✗ No alt text
<!-- Fixed -->
<img src="photo.jpg" alt="Project screenshot"> ✓
<!-- Error: Missing DOCTYPE -->
<html> ✗ No DOCTYPE
<head>...
<!-- Fixed -->
<!DOCTYPE html> ✓
<html>
<head>...
Browser DevTools HTML Errors
Check Console for HTML warnings:
// Open Console (F12)
// Look for warnings like:
"Warning: Invalid attribute value"
"Error: Element 'div' cannot be nested inside 'p'"
"Warning: Duplicate ID 'header'"
4. CSS Validation
Validate CSS to catch syntax errors and browser compatibility issues.
W3C CSS Validator
Using the CSS validator:
1. Go to https://jigsaw.w3.org/css-validator/
2. Choose input method:
- By URL
- By file upload
- By direct input
3. Select CSS profile (usually CSS level 3)
4. Click "Check"
5. Fix errors and warnings
Common CSS errors:
/* Error: Missing semicolon */
.button {
padding: 1rem
color: white; ✗ Missing semicolon above
}
/* Fixed */
.button {
padding: 1rem;
color: white; ✓
}
/* Error: Invalid property value */
.box {
width: 100; ✗ Missing unit
color: #FF; ✗ Invalid hex color
}
/* Fixed */
.box {
width: 100px; ✓
color: #FFFF00; ✓
}
/* Error: Unknown property */
.text {
text-colour: red; ✗ Should be "color"
font-waight: bold; ✗ Typo: "weight"
}
/* Fixed */
.text {
color: red; ✓
font-weight: bold; ✓
}
/* Error: Unclosed bracket */
.header {
background: blue;
padding: 1rem;
/* Missing closing } */
.footer { ✗ This won't work
background: gray;
}
/* Fixed */
.header {
background: blue;
padding: 1rem;
} ✓
.footer {
background: gray;
}
Browser DevTools CSS Debugging
Inspect styles:
1. Right-click element → Inspect
2. See "Styles" panel
3. Check which styles apply
4. Look for:
- Strikethrough (overridden)
- Warning icon (invalid)
- Computed values
5. Edit live to test fixes
Common CSS issues in DevTools:
Strikethrough property:
→ Another rule is overriding it (specificity issue)
Yellow warning icon:
→ Invalid property value
Faded property:
→ Not supported in this browser
No styles showing:
→ CSS file not loading (check Network tab)
5. JavaScript Debugging
Find and fix JavaScript errors using browser console.
Console Error Messages
Reading error messages:
// Error example
Uncaught ReferenceError: navToggle is not defined
at main.js:12
// Breakdown:
// "Uncaught" - Error wasn't caught/handled
// "ReferenceError" - Variable doesn't exist
// "navToggle is not defined" - Variable name
// "at main.js:12" - File and line number
Common JavaScript errors:
// Error 1: ReferenceError (variable doesn't exist)
console.log(userName); ✗ Variable not declared
// Fixed
const userName = "John";
console.log(userName); ✓
// Error 2: TypeError (wrong type/method)
const num = 5;
num.toUpperCase(); ✗ Numbers don't have toUpperCase()
// Fixed
const text = "hello";
text.toUpperCase(); ✓
// Error 3: SyntaxError (invalid syntax)
if (true { ✗ Missing closing parenthesis
console.log("test");
}
// Fixed
if (true) { ✓
console.log("test");
}
// Error 4: querySelector returns null
const button = document.querySelector('.btn');
button.addEventListener('click', handleClick); ✗ Button might not exist
// Fixed (check existence first)
const button = document.querySelector('.btn');
if (button) { ✓
button.addEventListener('click', handleClick);
}
Using Console for Debugging
Console methods:
// Log variables
console.log('User:', userName);
console.log('Data:', { name: 'John', age: 30 });
// Log warnings
console.warn('This feature is deprecated');
// Log errors
console.error('Failed to load data');
// Check condition
console.assert(age > 18, 'User must be 18+');
// Group related logs
console.group('User Info');
console.log('Name:', name);
console.log('Email:', email);
console.groupEnd();
// Time operations
console.time('Data fetch');
fetchData();
console.timeEnd('Data fetch'); // Shows elapsed time
// Clear console
console.clear();
Breakpoints and Debugging
Setting breakpoints in DevTools:
1. Open Sources tab in DevTools
2. Find your JavaScript file
3. Click line number to add breakpoint (blue marker)
4. Trigger the code (click button, etc.)
5. Execution pauses at breakpoint
6. Use controls:
- Resume (continue execution)
- Step over (next line)
- Step into (enter function)
- Step out (exit function)
7. Inspect variables in Scope panel
Debugging workflow example:
// Problem: Modal not opening
function openModal() {
const modal = document.querySelector('.modal');
modal.classList.add('active'); // Error occurs here
}
// Debugging steps:
// 1. Set breakpoint on line 2
// 2. Click button to open modal
// 3. Execution pauses
// 4. Check "modal" variable in Scope
// 5. Realize: modal is null (doesn't exist)
// 6. Check HTML - class is 'image-modal', not 'modal'
// 7. Fix selector
// Fixed code:
function openModal() {
const modal = document.querySelector('.image-modal'); ✓
if (modal) { // Add safety check
modal.classList.add('active');
}
}
6. Network Performance Testing
Test how fast your site loads and identify bottlenecks.
Using DevTools Network Tab
Network tab workflow:
1. Open DevTools → Network tab
2. Refresh page (Ctrl+R)
3. See all loaded files
4. Check:
- Total load time
- File sizes
- Slow-loading files
- Failed requests (red)
5. Sort by size to find large files
6. Optimize the biggest files
Network tab columns explained:
Name: File name
Status: HTTP code (200 = OK, 404 = Not found)
Type: File type (document, stylesheet, script, image)
Size: File size (aim for <200 KB for images)
Time: Load time (aim for <1s per file)
Waterfall: Visual timeline of loading
Performance targets:
Good page load time:
Mobile: < 3 seconds
Desktop: < 2 seconds
File size limits:
HTML: < 100 KB
CSS: < 100 KB
JavaScript: < 200 KB
Images: < 200 KB each
Total page: < 2 MB
Google Lighthouse Audit
Running Lighthouse:
1. Open DevTools
2. Go to Lighthouse tab
3. Select categories:
✓ Performance
✓ Accessibility
✓ Best Practices
✓ SEO
4. Choose device (mobile/desktop)
5. Click "Generate report"
6. Review scores (aim for 90+)
7. Fix issues listed
Lighthouse metrics:
Performance (aim for 90+):
- First Contentful Paint (< 1.8s)
- Largest Contentful Paint (< 2.5s)
- Time to Interactive (< 3.8s)
- Cumulative Layout Shift (< 0.1)
Opportunities to improve:
- Optimize images
- Eliminate render-blocking resources
- Reduce JavaScript execution time
- Use efficient cache policy
Example Lighthouse report:
Performance: 85 ⚠ (needs improvement)
Opportunities:
× Properly size images (save 500 KB)
× Defer offscreen images (save 1.2s)
× Remove unused CSS (save 45 KB)
Accessibility: 95 ✓ (good)
Passed audits:
✓ Image alt attributes
✓ Contrast ratios
Issues:
× Links do not have discernible text
Best Practices: 92 ✓
SEO: 100 ✓
7. Accessibility Testing
Ensure your site works for all users, including those with disabilities.
WAVE Accessibility Tool
Using WAVE:
1. Go to https://wave.webaim.org/
2. Enter your URL
3. Click "View report"
4. Check for:
- Errors (must fix)
- Alerts (review)
- Features (good practices)
- Structural elements
- Contrast errors
Common accessibility errors:
<!-- Error: Missing alt text -->
<img src="photo.jpg"> ✗
<!-- Fixed -->
<img src="photo.jpg" alt="Team photo from 2024"> ✓
<!-- Error: Empty link -->
<a href="contact.html"></a> ✗
<!-- Fixed -->
<a href="contact.html">Contact Us</a> ✓
<!-- Error: Low contrast -->
<p style="color: #999; background: #fff;">Text</p> ✗ 2.8:1 ratio
<!-- Fixed -->
<p style="color: #666; background: #fff;">Text</p> ✓ 5.7:1 ratio
<!-- Error: Skip link missing -->
<body>
<header>...</header> ✗ No skip link
<!-- Fixed -->
<body>
<a href="#main" class="skip-link">Skip to content</a> ✓
<header>...</header>
axe DevTools Extension
Install and use axe:
1. Install axe DevTools browser extension
2. Open DevTools
3. Click "axe DevTools" tab
4. Click "Scan ALL of my page"
5. Review issues by severity:
- Critical (fix immediately)
- Serious (fix soon)
- Moderate (important)
- Minor (nice to have)
6. Click issue for details and fix guidance
Manual Accessibility Testing
Keyboard navigation test:
Tab key: Move to next interactive element
Shift+Tab: Move to previous element
Enter/Space: Activate button/link
Arrow keys: Navigate within components
Escape: Close modal/dropdown
Test checklist:
□ Can reach all interactive elements
□ Focus indicator is visible
□ Logical tab order
□ Can activate all buttons with Enter
□ Can close modals with Escape
□ No keyboard traps (can always escape)
Screen reader testing:
Windows: NVDA (free)
- Download from nvaccess.org
- Insert+Q to quit
- Down arrow to read
Mac: VoiceOver (built-in)
- Cmd+F5 to start/stop
- Ctrl+Opt+Right Arrow to navigate
- Ctrl+Opt+Space to activate
Test checklist:
□ All images have alt text
□ Headings read in order
□ Links make sense out of context
□ Form labels are associated
□ Buttons describe their action
8. Common Bugs and Fixes
CSS Layout Issues
Problem: Content overflowing container
/* Problem */
.container {
width: 1000px; /* Fixed width */
}
/* On mobile (320px wide): Horizontal scroll ✗ */
/* Fix */
.container {
max-width: 1000px; /* Maximum, but can shrink */
width: 100%;
padding: 0 1rem; /* Spacing on sides */
}
Problem: Vertical alignment not working
/* Problem */
.button {
vertical-align: middle; /* Doesn't work on block elements */
}
/* Fix (Flexbox) */
.button {
display: flex;
align-items: center;
justify-content: center;
}
Problem: Image aspect ratio distortion
/* Problem */
.gallery img {
width: 300px;
height: 200px; /* Squashes/stretches image */
}
/* Fix */
.gallery img {
width: 300px;
height: 200px;
object-fit: cover; /* Crops to fit, maintains aspect */
}
JavaScript Common Errors
Problem: Element not found (null error)
// Problem
const button = document.querySelector('.submit-btn');
button.addEventListener('click', handleClick); // Error if button doesn't exist
// Fix: Check existence
const button = document.querySelector('.submit-btn');
if (button) {
button.addEventListener('click', handleClick);
}
Problem: Timing - script runs before DOM ready
// Problem: Script in <head>, elements don't exist yet
const nav = document.querySelector('nav'); // Returns null
// Fix 1: Move script to end of <body>
// Fix 2: Wait for DOM ready
document.addEventListener('DOMContentLoaded', () => {
const nav = document.querySelector('nav'); // Now exists
});
// Fix 3: Use defer attribute
<script src="main.js" defer></script>
Problem: Click event not working on dynamically added elements
// Problem: Event added before element created
const button = document.querySelector('.dynamic-btn');
button.addEventListener('click', handleClick); // Button added later
// Fix: Event delegation on parent
document.body.addEventListener('click', (e) => {
if (e.target.matches('.dynamic-btn')) {
handleClick();
}
});
Mobile-Specific Issues
Problem: Text too small on mobile
/* Problem */
body {
font-size: 14px; /* Too small on mobile */
}
/* Fix */
body {
font-size: 16px; /* Minimum for mobile readability */
}
Problem: Buttons too small to tap
/* Problem */
.btn {
padding: 0.25rem 0.5rem; /* Too small for fingers */
}
/* Fix (minimum 44×44px touch target) */
.btn {
padding: 0.75rem 1.5rem; /* At least 44px tall */
min-width: 44px;
min-height: 44px;
}
9. Testing Checklist
Pre-Launch Testing Checklist
Functionality:
□ All links work (no 404 errors)
□ Forms submit correctly
□ Buttons perform expected actions
□ Navigation menu works on all pages
□ Search functionality works (if applicable)
□ No JavaScript console errors
□ All images load
□ Videos play correctly
Cross-Browser:
□ Tested on Chrome
□ Tested on Firefox
□ Tested on Safari
□ Tested on Edge
□ Tested on mobile browsers
Responsive:
□ Mobile (320-480px)
□ Tablet (768-1024px)
□ Desktop (1280px+)
□ Portrait and landscape orientations
□ Text readable on all sizes
□ No horizontal scrolling
Code Quality:
□ HTML validates (W3C)
□ CSS validates (W3C)
□ No JavaScript errors in console
□ No 404 errors (missing files)
□ Lighthouse score 90+ on all metrics
Performance:
□ Page loads in under 3 seconds
□ Images optimized and compressed
□ Lazy loading implemented
□ CSS/JS minified (for production)
□ Total page size under 2 MB
Accessibility:
□ All images have alt text
□ Headings in logical order
□ Keyboard navigation works
□ Focus states visible
□ Color contrast meets WCAG AA (4.5:1)
□ WAVE shows no errors
□ Screen reader friendly
SEO:
□ Unique title on each page
□ Meta descriptions on all pages
□ Headings properly structured
□ Image alt text descriptive
□ Links descriptive (not "click here")
□ Sitemap exists (for larger sites)
Content:
□ Spell-check all text
□ Contact information correct
□ Social media links work
□ Copyright year current
□ No Lorem Ipsum placeholder text
□ All content proofread
10. Debugging Workflow
Systematic Debugging Process
Step 1: Identify the problem
- What is broken?
- When does it break?
- On which browsers/devices?
- What's the expected behavior?
Step 2: Reproduce the issue
- Can you make it happen consistently?
- What are the exact steps?
- Does it happen every time?
Step 3: Isolate the cause
- Check browser console for errors
- Inspect the element (DevTools)
- Check Network tab for failed requests
- Comment out code to narrow down issue
Step 4: Fix the issue
- Make the smallest change possible
- Test the fix immediately
- Verify it doesn't break anything else
Step 5: Document the solution
- Note what caused the problem
- Document the fix
- Add comments to code if needed
Example Debugging Session
Problem: "View Project" buttons not working
// Step 1: Identify
// Clicking project cards should open modal, but nothing happens
// Step 2: Reproduce
// Click any project card - consistently fails
// Step 3: Isolate
// Check console:
// > Uncaught TypeError: Cannot read property 'classList' of null
// > at openModal (main.js:45)
// Check code:
function openModal() {
const modal = document.querySelector('.modal');
modal.classList.add('active'); // Line 45 - error here
}
// Use console.log to debug:
console.log('Modal element:', modal); // Logs: null
// Inspect HTML - class is 'image-modal', not 'modal'!
// Step 4: Fix
function openModal() {
const modal = document.querySelector('.image-modal'); // Fixed selector
if (modal) { // Added safety check
modal.classList.add('active');
} else {
console.error('Modal element not found');
}
}
// Step 5: Document
// Added comment explaining the correct class name
// Noted in documentation for future reference
11. Practical Exercises
Exercise 5.1: Cross-Browser Testing
Test your portfolio on multiple browsers:
- Open site in Chrome, Firefox, Safari, Edge
- Document any visual differences
- Identify and fix browser-specific issues
- Verify all functionality works everywhere
Exercise 5.2: Responsive Testing
Test all breakpoints:
- Use DevTools to test mobile (375px)
- Test tablet (768px)
- Test desktop (1440px)
- Fix any layout issues at each size
- Test on at least one real mobile device
Exercise 5.3: Code Validation
Validate all code:
- Run HTML through W3C validator
- Fix all HTML errors
- Run CSS through CSS validator
- Fix all CSS errors
- Check JavaScript console for errors
Exercise 5.4: Performance Audit
Run Lighthouse audit:
- Open Lighthouse in DevTools
- Run performance audit
- Identify top 3 issues
- Fix the issues
- Re-run to verify improvements
Exercise 5.5: Accessibility Testing
Test accessibility:
- Run WAVE accessibility check
- Fix any errors found
- Test keyboard navigation (Tab, Enter, Esc)
- Verify all images have alt text
- Check color contrast ratios
12. Knowledge Check
Question 1: What's the first place to check when debugging JavaScript issues?
Show answer
The browser console (F12 → Console tab). It shows error messages with file names and line numbers, making it the fastest way to identify JavaScript problems.Question 2: What does a Lighthouse performance score of 65 indicate?
Show answer
Needs improvement. Aim for 90+ for good performance. Scores below 90 indicate issues like unoptimized images, render-blocking resources, or slow JavaScript execution.Question 3: What's the minimum color contrast ratio for normal text?
Show answer
4.5:1 for normal text (WCAG AA standard). Large text (18px+ or 14px+ bold) requires 3:1 minimum. This ensures readability for users with visual impairments.Question 4: Why test on real mobile devices, not just DevTools?
Show answer
Real devices show actual touch interactions, performance, and rendering that emulation can't perfectly replicate. Network speeds and device capabilities vary significantly.Question 5: What does the strikethrough on a CSS property in DevTools mean?
Show answer
The property is being overridden by another CSS rule with higher specificity. The strikethrough property is not being applied to the element.13. Common Testing Mistakes
Testing Only on Desktop
Problem:
✗ Only tested on MacBook (1440px screen)
✗ Site looks perfect on desktop
✗ Deploy without mobile testing
→ Mobile users see broken layout
Solution:
✓ Test mobile first (375px)
✓ Test tablet (768px)
✓ Test desktop (1440px)
✓ Test on real phone if possible
Ignoring Console Errors
Problem:
// Console shows:
> Uncaught TypeError: Cannot read...
> 404 Not Found: style.css
✗ Ignored because "site seems to work"
→ JavaScript features broken
→ Styles not loading
Solution:
✓ Fix ALL console errors before launch
✓ No errors = cleaner, more reliable code
✓ Errors indicate real problems
Not Testing Different Browsers
Problem:
✗ Only tested in Chrome
→ Flexbox gap doesn't work in Safari 14.0
→ CSS Grid issues in older browsers
→ Users see broken layouts
Solution:
✓ Test Chrome, Firefox, Safari, Edge
✓ Check caniuse.com for feature support
✓ Provide fallbacks for older browsers
14. Key Takeaways
- Test early and often - Don't wait until the end
- Cross-browser testing is essential - Test Chrome, Firefox, Safari, Edge
- Mobile-first approach - Test mobile sizes first
- Use DevTools extensively - Console, Network, Lighthouse
- Validate your code - W3C HTML/CSS validators
- Fix all console errors - No exceptions
- Accessibility is not optional - Use WAVE and axe tools
- Performance matters - Aim for Lighthouse 90+
- Test on real devices - DevTools emulation isn't perfect
- Document issues and fixes - Learn from debugging
15. Further Resources
Testing Tools:
Browser DevTools:
Performance:
Accessibility:
Congratulations!
You've completed the Web Project Development course! You now have the skills to:
- Plan and prototype professional websites
- Build semantic, well-structured HTML
- Create scannable, user-friendly content
- Add optimized media and interactions
- Test, debug, and ensure quality before launch
Your personal homepage portfolio is ready to deploy and showcase your skills to the world!
Next Steps
- Deploy your portfolio - Put it live on the web
- Continue learning - Explore JavaScript frameworks (Vue, React)
- Build more projects - Practice makes perfect
- Get feedback - Share with others and iterate
- Keep coding - The journey has just begun!