# Chrome DevTools ## 1. Opening DevTools ``` F12 -> Open/close DevTools Ctrl+Shift+I (Cmd+Opt+I) -> Open DevTools Ctrl+Shift+J -> Open DevTools at Console tab Ctrl+Shift+C -> Open DevTools at Elements, with Inspect mode Right-click -> Inspect -> Inspect specific element Ctrl+Shift+P -> Command palette (like VS Code Ctrl+Shift+P) ``` --- ## 2. DevTools Tabs Overview | Tab | Purpose | Use When | | :--- | :--- | :--- | | **Elements** | Inspect and live-edit HTML/CSS structure | Debugging layout, finding selectors for scraping ✅ | | **Console** | Run JavaScript, see errors and logs | Testing code snippets, debugging JS errors ✅ | | **Network** | See all HTTP requests and responses | Debugging APIs, finding endpoints, checking auth ✅ | | **Sources** | View JS files, set breakpoints, debug | Step-through debugging JS code | | **Application** | Cookies, LocalStorage, SessionStorage, Cache | Checking auth tokens, session state ✅ | | **Performance** | Record and analyze page performance | Finding rendering bottlenecks | | **Memory** | Heap snapshots, memory leaks | Diagnosing memory-related crashes | | **Lighthouse** | Automated audit (perf, SEO, accessibility) | Pre-deploy quality check | --- ## 3. Network Tab - Complete Guide (Exam Critical) The most important tab for API debugging and data science tasks. ### Layout ``` Toolbar: Record (red dot) | Clear | Filter bar | Import/Export HAR Filter: All | XHR | JS | CSS | Img | Media | Font | Doc | WS | Other Request List: Name | Status | Type | Initiator | Size | Time | Waterfall Bottom pane (click a request): Headers | Payload | Preview | Response | Initiator | Timing | Cookies ``` ### Filtering Requests | Filter | Shows | | :--- | :--- | | **XHR** | AJAX/fetch API calls only ✅ (most useful for APIs) | | **Fetch/XHR** | All modern fetch() and XMLHttpRequest calls ✅ | | **Doc** | HTML documents | | **JS** | JavaScript files | | **Img** | Images | | **WS** | WebSocket connections | | **Ctrl+F** | Search across all request names/URLs | ``` Filter box accepts: domain:api.example.com -> requests to specific domain status-code:404 -> filter by status code method:POST -> filter by HTTP method -method:GET -> exclude GET requests (negation with -) larger-than:100k -> filter by response size ``` ### Headers Tab (Inside a Request) ``` Request Headers: :method: GET -> HTTP method :path: /api/data -> URL path :scheme: https -> protocol Content-Type: application/json Authorization: Bearer sk-... ✅ where API keys live Cookie: session=abc123 Response Headers: Content-Type: application/json Cache-Control: no-cache X-RateLimit-Remaining: 57 ✅ check remaining API quota Retry-After: 60 ✅ how long to wait if 429 Set-Cookie: session=new_value ``` ### Payload Tab (POST/PUT Request Body) ``` Shows request body - what you SENT to the server: Form Data: key=value&key2=value2 JSON: {"query": "hello", "model": "gpt-4o"} Raw: Full raw body ✅ Use to verify your POST body is correct ✅ Compare with API docs to find missing/wrong fields ``` ### Response Tab (What Server Sent Back) ``` Shows exact response body: JSON response ✅ see the full API response structure HTML page source Binary encoded data (images, files) ✅ Use to verify nested JSON structure before writing code: response_json['weather'][0]['description'] <- confirmed from Response tab ``` ### Timing Tab (Performance Breakdown) | Phase | Meaning | | :--- | :--- | | **Queueing** | Browser waiting to send (too many concurrent requests) | | **Stalled** | Waiting for connection | | **DNS Lookup** | Time to resolve domain to IP | | **Initial Connection** | TCP handshake | | **SSL** | HTTPS encryption negotiation | | **TTFB** | Time to First Byte - server processing time ✅ | | **Content Download** | Downloading response body | - High **TTFB** = server is slow (backend issue) - High **Content Download** = large response, slow network - High **DNS** = try local caching or CDN --- ## 4. Console Tab - Complete Guide ### Key Uses ```javascript // Run any JavaScript document.querySelectorAll('a').length // count all links JSON.parse(document.body.innerText) // parse JSON shown on page ✅ // Copy data from page to clipboard copy(document.body.innerText) // copies all text ✅ copy(JSON.stringify(data, null, 2)) // copy formatted JSON // Extract all links from page Array.from(document.querySelectorAll('a')).map(a => a.href) // Extract table data let rows = document.querySelectorAll('table tr'); Array.from(rows).map(r => Array.from(r.cells).map(c => c.innerText)); // Fetch API data directly from console ✅ fetch('https://api.example.com/data') .then(r => r.json()) .then(data => console.log(data)) .then(data => copy(JSON.stringify(data))) // copy to clipboard // Monitor XHR/fetch calls monitorEvents(window, 'fetch') // watch all fetch calls ``` ### Console Log Levels | Method | Level | Use | | :--- | :--- | :--- | | `console.log()` | Info | General debugging | | `console.warn()` | Warning | Non-critical issues | | `console.error()` | Error | Errors ✅ | | `console.table(data)` | Info | Display array/objects as table ✅ | | `console.dir(element)` | Info | Full object structure | | `console.time('label')` | Info | Start timer | | `console.timeEnd('label')` | Info | End timer, print duration | ### Filter Errors in Console ``` Console toolbar -> Levels dropdown: Verbose | Info | Warnings | Errors ✅ Filter box: type keyword to filter messages ``` --- ## 5. Application Tab - Session & Storage ``` Application Tab -> Storage: Cookies -> session tokens, auth cookies ✅ LocalStorage -> persistent client-side data (survives page reload) SessionStorage -> tab-only data (cleared when tab closes) IndexedDB -> structured client-side database Cache Storage -> service worker cache Click on Cookies -> select domain -> see name/value/expiry/flags ✅ Check cookies to find: - session IDs - auth tokens - CSRF tokens - tracking identifiers ``` --- ## 6. Sources Tab - JavaScript Debugging ``` Sources Tab: Page -> all JS/CSS files loaded ✅ Snippets -> save reusable JS scripts Overrides -> replace remote files with local versions (advanced) Breakpoints: Click line number -> set breakpoint ✅ F5 or Ctrl+\ -> resume execution F10 -> step over (next line) F11 -> step into (enter function) Shift+F11 -> step out of current function Watch expressions: Right panel -> Watch -> + -> type variable name -> watches value in real-time Conditional breakpoints: Right-click line number -> "Add conditional breakpoint" Condition: i > 100 -> only pauses when condition is true ✅ ``` --- ## 7. Finding Hidden APIs in Network Tab (Exam Critical) This is how you "reverse-engineer" a website's API for data extraction. ``` Step-by-step: 1. Open DevTools (F12) -> Network tab 2. Clear existing requests (trash icon) 3. Filter: XHR or Fetch/XHR ✅ 4. Interact with the website (search, click load more, scroll) 5. New requests appear in Network tab 6. Click the API request -> Headers tab -> copy Request URL ✅ 7. Check Payload tab -> see what params were sent 8. Check Response tab -> see exact JSON structure 9. Replicate with requests.get(url, params=...) in Python ✅ ✅ This lets you bypass the HTML frontend and call the raw API directly ``` ### Copying a Request as Python Code ``` Right-click a request in Network tab: -> Copy -> Copy as cURL ✅ copy as curl command -> Copy -> Copy as fetch ✅ copy as JavaScript fetch -> (use a browser extension) Copy as Python requests ``` --- ## 8. JSON Handling in DevTools ```javascript // Pretty-print raw JSON on a page JSON.stringify(JSON.parse(document.body.innerText), null, 2) // Access deeply nested JSON from console let data = await fetch('/api/endpoint').then(r => r.json()) data.results[0].company.address.city // navigate nested structure // Copy nested value copy(data.results.map(r => r.name)) // copies array to clipboard ✅ // Filter and extract specific fields data.items .filter(item => item.status === 'active') .map(item => ({id: item.id, name: item.name})) ``` --- ## 9. XHR Interception & Script Injection ```javascript // Override fetch to log all API calls ✅ const originalFetch = window.fetch; window.fetch = function(url, options) { console.log('Fetch called:', url, options); return originalFetch(url, options).then(response => { console.log('Response status:', response.status, 'URL:', url); return response; }); }; // Override XMLHttpRequest to log all XHR calls const originalOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function(method, url) { console.log('XHR called:', method, url); return originalOpen.apply(this, arguments); }; // Monitor specific endpoint let endpointData = []; const origFetch = window.fetch; window.fetch = async (url, opts) => { const res = await origFetch(url, opts); if (url.includes('/api/search')) { const data = await res.clone().json(); endpointData.push(data); // ✅ capture all responses console.log('Captured:', data); } return res; }; ``` --- ## 10. Server Log Simulation via Console ```javascript // Simulate reading server logs by monitoring page errors window.onerror = function(message, source, line, col, error) { console.log(`[ERROR] ${message} at ${source}:${line}`); }; // Monitor all console errors const origError = console.error; console.error = function(...args) { // Store errors for analysis sessionStorage.setItem('errors', JSON.stringify([...JSON.parse(sessionStorage.getItem('errors') || '[]'), args]) ); origError.apply(console, args); }; // Check for failed requests (4xx/5xx) // -> Network tab -> Status code column -> red = failed ✅ // -> Filter: status-code:404 to find all 404s ``` --- ## 11. Useful DevTools Keyboard Shortcuts | Shortcut | Action | | :--- | :--- | | `Ctrl+R` | Reload page | | `Ctrl+Shift+R` | Hard reload (bypass cache) ✅ | | `Ctrl+F` in Network | Search request names/URLs | | `Ctrl+F` in Console | Search console output | | `Esc` | Toggle Console drawer (when in other tab) ✅ | | `Ctrl+Shift+P` | DevTools command palette | | `$0` in Console | Reference currently selected element | | `$$('selector')` | Shorthand for `document.querySelectorAll()` ✅ | | `$_` | Last evaluated expression in Console | --- ## 12. Debugging Common Problems | Problem | Where to Look | What to Do | | :--- | :--- | :--- | | API returns 401 | Network -> Headers tab | Check Authorization header exists and format is correct | | API returns 429 | Network -> Response headers | Check `Retry-After` header, add `time.sleep()` ✅ | | Wrong JSON structure | Network -> Response tab | Navigate JSON to find correct nested path ✅ | | Login session not maintained | Application -> Cookies | Check session cookie is being set and not expired | | Page loads slow | Network -> Timing (TTFB) | High TTFB = server slow; optimize backend ✅ | | JS error preventing scrape | Console -> Errors tab | Read stack trace to find failing script | | CORS error blocking API | Console | Server must add `Access-Control-Allow-Origin` header | | API endpoint URL unknown | Network -> XHR filter | Interact with page and watch new requests ✅ | | Data not in page source | Sources -> Elements | Data is JS-rendered; use Selenium/Playwright ✅ | --- ## 13. Mobile Simulation ``` Toolbar -> Toggle Device Toolbar (Ctrl+Shift+M) Device selection: Responsive -> drag to custom size iPhone 15, iPad, Galaxy S22, etc. Simulates: Screen size Touch events (instead of click) Mobile user-agent string DPI ratio ✅ Use to test mobile view of website ✅ Use to trigger mobile-specific API calls (some sites serve different data to mobile) ``` --- ## 14. Lighthouse - Automated Audit ``` Lighthouse tab -> Generate report Audits: Performance -> FCP, LCP, TBT, CLS scores Accessibility -> screen reader compatibility Best Practices -> deprecated APIs, security SEO -> meta tags, structured data ✅ Run before deploying a static site to find issues ✅ Identifies missing meta descriptions, slow images, etc. ``` --- ## 15. Quick Reference Card ``` Finding an API endpoint: Network -> XHR filter -> interact with page -> copy URL ✅ Debugging API authentication: Network -> click request -> Headers -> check Authorization ✅ Inspecting JSON response: Network -> click request -> Response tab ✅ Checking cookies/sessions: Application -> Cookies ✅ Running JS snippets: Console tab -> type code ✅ Extracting page data via JS: console: copy($$('selector').map(el => el.innerText)) ✅ Simulating mobile: Ctrl+Shift+M -> toggle device toolbar ✅ Hard reload: Ctrl+Shift+R (bypasses cache) ✅ ```