Open this lesson in your favourite AI. It'll walk you through the why, explain the demo, and quiz you on the try-it list.
The browser's developer tools are the most powerful instrument a QA engineer has. Without them, you can only test what's visible on screen. With them, you can intercept every HTTP request and response (Network tab), read and manipulate cookies/localStorage/sessionStorage (Application tab), observe and run JavaScript in real time (Console), inspect and edit DOM elements (Elements tab), and profile rendering performance (Performance tab). Every credible bug report for a web application should have supporting DevTools evidence. 'It showed an error' is a claim; a Network tab screenshot showing the 401 response with the full request headers is proof.
Browser DevTools Console exposes the runtime state that the UI deliberately hides from end users — session tokens, feature flags, cached API responses, and the exact JavaScript errors that caused a visual glitch. Running these snippets during exploratory testing converts a vague 'the page looks wrong' into a specific 'the JWT in localStorage expired 4 hours ago and the app silently cached stale data.' That specificity is what moves a bug from P3 to P1.
// ── Paste these into the browser Console (F12) on any web app ──
// 1. Read all cookies
console.table(
document.cookie.split('; ').map(c => {
const [name, ...v] = c.split('=');
return { name, value: v.join('=') };
})
);
// 2. Read localStorage and sessionStorage
console.group('LocalStorage');
Object.entries(localStorage).forEach(([k,v]) => {
try { console.log(k, JSON.parse(v)); }
catch { console.log(k, v); }
});
console.groupEnd();
// 3. Check if a JWT token is valid and read its claims (without verifying signature)
function decodeJWT(token) {
const parts = token.split('.');
if (parts.length !== 3) return null;
const payload = JSON.parse(atob(parts[1].replace(/-/g, '+').replace(/_/g, '/')));
const expiresAt = new Date(payload.exp * 1000);
const isExpired = Date.now() > payload.exp * 1000;
return { ...payload, expiresAt: expiresAt.toISOString(), isExpired };
}
const token = localStorage.getItem('auth_token') || sessionStorage.getItem('token');
if (token) console.log('JWT claims:', decodeJWT(token));
// 4. Intercept all fetch() calls to log request/response (before DevTools Network tab)
const originalFetch = window.fetch;
window.fetch = async (...args) => {
console.log('[FETCH]', args[0], args[1]?.method || 'GET');
const res = await originalFetch(...args);
console.log('[FETCH RESPONSE]', res.status, res.url);
return res;
};
console.log('fetch() interceptor active — all API calls will be logged above');node main.jssession, sid, auth, or JSESSIONID) and note its attributes — does it have HttpOnly? Secure? SameSite? What do these mean for security?Use these three in order. Each builds on the one before.
In one paragraph, explain the difference between cookies, localStorage, and sessionStorage. When does each expire, what can JavaScript access, and which is sent to the server automatically with every request?
Walk me through how to use the Network tab to diagnose why a login is failing. What request do you look for, what status code indicates the failure, what in the request headers might be wrong, and what in the response body gives you the server's error message?
A user reports 'the app is slow.' Walk me through a full browser DevTools performance investigation: Network tab (what to look for), Performance tab (what to record), Console (what warnings appear), and Lighthouse audit (what score tells you what). For each tool: what specific number triggers an investigation and what's the fix pattern?