DevTools for Testers
The browser's built-in developer tools are a tester's X-ray. Learn to open them, read the Elements, Console, Network and Application panels, and use them to find and prove bugs.
You’re testing a food delivery website. You add a pizza, pay with a test card and see a cheerful green toast: “Order placed!” But the order never shows up in My orders. You try again. Same thing.
You could write “Ordering doesn’t work”. Or you could press F12, open the Network panel, and see that POST /api/orders came back with 500 Internal Server Error, while the page showed a success message anyway. Now your bug report says exactly what failed, where, and why it’s worse than it looks: users think they ordered food that’s never coming.
That’s what browser DevToolsDevToolsDeveloper tools built into browsers for inspecting pages, network traffic and errors.Open in glossary → give you: an X-ray of the website. You don’t need to read code to use them. You just need to know where to look.
Why it matters
DevTools turn “something is wrong” into evidence a developer can act on:
- You see what the user can’t. Failed requests, JavaScript errors, slow servers and leaked data are invisible on screen.
- Your bug reports get better. A status code, an error message and a request payload save developers hours. Bugs with that evidence get fixed first.
- You can test things that are hard to reach. Slow networks, phone screen sizes, long text, logged-out states and hover styles, all from your desk.
- You can decide who owns the bug. Wrong data in the response? Backend. Right data shown wrong? Frontend. That’s half the triage done.
Opening DevTools
| Browser | Windows / Linux | Mac | Also |
|---|---|---|---|
| Chrome / Edge | F12 or Ctrl+Shift+I | Cmd+Option+I | Right-click anything → Inspect |
| Firefox | F12 or Ctrl+Shift+I | Cmd+Option+I | Right-click → Inspect |
| Safari | – | Cmd+Option+I | Must be switched on first (see below) |
Handy shortcuts in Chrome:
- Ctrl/Cmd+Shift+C: jump straight to “inspect element” mode.
- Ctrl+Shift+J (Mac: Cmd+Option+J): open the Console directly.
- Ctrl/Cmd+Shift+P inside DevTools: the Command Menu, a search box for every DevTools feature. If you forget where something is, type its name here.
You can dock DevTools to the bottom, right or left of the window, or pop it out into its own window, using the ⋮ menu in its top-right corner. Bottom docking leaves the page at full width, which is best when you’re testing layouts.
The panels testers actually use
DevTools have more than a dozen panels. Testers live in four of them, plus a few extra tools:
Elements
The page’s HTML and CSS. Inspect any element, edit text live, check styles, force :hover and :focus.
Ask: is it built right? Is the text, label or style correct?
Console
JavaScript errors, warnings and log messages from the page.
Ask: did something crash behind the scenes?
Network
Every request the page makes: status codes, timing, what was sent and what came back.
Ask: did the server really succeed? Is it fast? Is the data right?
Application
Cookies, local storage, session storage and a “Clear site data” button.
Ask: what does the site remember about me, and should it?
Plus three tools you’ll use regularly: device mode (phone screen sizes), Lighthouse (automatic quality audits) and screenshots. We’ll cover them after the demo.
Try it: DevTools on a real-feeling shop
Below is FreshCart, a grocery page with a working copy of DevTools docked underneath. Everything you do on the page shows up in the panels, just like in a real browser.
Weekly deals
Prices valid until Sunday
Recommended for you
| Name | Status | Type | Size | Time |
|---|
Recording network activity… Reload the page or interact with it.
Elements: inspect and poke the page
The Elements panel shows the live HTML (the DOM) on the left and the CSS that applies to the selected element on the right.
What testers use it for:
- Inspect an element. Right-click it on the page → Inspect, or use the picker icon. You’ll see its tag, classes and attributes. Is that “button” really a
<button>, or a<div>that keyboards can’t reach? Does the image havealttext? - Edit text to test long content. Double-click a text node and type something long: a 60-character product name, a German translation, a name like “Maximiliane Oberhauser-Wittgenstein”. Does it wrap, get cut off with an ellipsis, or overflow its card? This is the fastest truncationTruncationText that gets cut off because it doesn't fit its space.Open in glossary → test there is.
- Check CSS values. Is the font size really 16px? Is the color the one in the design? The Computed tab shows the final value after all rules are applied.
- Force states. Hover and focus styles disappear the moment you move the mouse to DevTools. Click :hov in the Styles pane (or right-click the node → Force state) and tick
:hover,:focus,:focus-visibleor:active. Now you can check that keyboard focus is visible, which is an important accessibility testingAccessibility testingChecking that people with disabilities can use the product, for example with a screen reader.Open in glossary → check.
Console: what crashed behind the scenes
The Console collects messages from the page’s JavaScript:
| Level | Looks like | What it usually means for you |
|---|---|---|
| Error | Red line, red ✕ icon | Something failed: an exception, a failed request, a blocked resource. Always worth a look. |
| Warning | Yellow line, ⚠ icon | Something is deprecated, risky or odd. Often harmless, sometimes an early sign of a bug. |
| Info / log | Plain text | Messages developers left on purpose (“Loaded 4 products”). Useful context. |
What a red error means for your bug report. An error like TypeError: Cannot read properties of undefined (reading 'map') means the code tried to use data that wasn’t there, and stopped. If it appears exactly when you click something and that action doesn’t work, you’ve likely found the cause. Copy the message and the file and line number on the right (e.g. app.js:214). Expand it with the ▸ arrow to see the stack trace, which tells developers which functions were running.
Two kinds of red lines show up all the time:
Failed to load resource: the server responded with a status of 404 (Not Found): the browser couldn’t load a file or API call. Check the Network panel for the full story.Uncaught TypeError…/Uncaught (in promise)…: the page’s own code crashed.
In Chrome, the console is cleared on every page load. Tick Preserve log in the Console settings (⚙) when a bug happens just before a redirect, such as after submitting a login form.
Network: what really happened
This is the panel testers use most. Every row is one request: the HTML page, stylesheets, scripts, images, fonts and the API calls (shown as fetch or xhr) where the real data travels.
The key columns:
- Name: the file or endpointEndpointA specific API address the app calls, like GET /api/products or POST /api/login.Open in glossary →, e.g.
products?category=fruit. - Status: the HTTP status codeHTTP status codeA three-digit number in every server response: 200 means OK, 404 not found, 500 server error.Open in glossary →. Failed rows turn red.
- Type:
document,stylesheet,script,fetch,png/webp… - Size: how much was transferred.
(disk cache)or(memory cache)means it came from the cacheCacheStored copies of data or files that make apps and websites load faster.Open in glossary →, not the server. - Time: how long it took. Anything over 1 second for an API call deserves attention.
Status codes in 30 seconds
| Range | Meaning | Examples you’ll see |
|---|---|---|
| 2xx | Success | 200 OK, 201 Created, 204 No Content |
| 3xx | Redirect / not modified | 301/302 redirect, 304 Not Modified (use your cached copy) |
| 4xx | The request was wrong | 400 Bad Request, 401 Unauthorized (not logged in), 403 Forbidden (not allowed), 404 Not Found, 422 validation error, 429 Too Many Requests |
| 5xx | The server failed | 500 Internal Server Error, 502 Bad Gateway, 503 Service Unavailable, 504 Gateway Timeout |
A 5xx is almost always a bug. A 4xx may be correct (wrong password → 401) or a bug (a valid form → 400). What matters most is that the page tells the user the truth about what happened.
Click a row for the details
- Headers: the full URL, methodHTTP methodThe type of request: GET reads data, POST creates, PUT/PATCH updates, DELETE removes.Open in glossary → (
GET,POST,PUT,DELETE), status, and the request and response headers (cookies, content type, caching). - Payload: what the page sent, e.g. the form data. Is the right value going out? Is a password visible in a URL? (It should never be.)
- Preview / Response: what the server sent back, usually JSONJSONA simple text format for data, used by most APIs, like {"name": "Anna", "age": 31}.Open in glossary →. Is the data correct? Is there data that shouldn’t be there, like another user’s email or internal fields?
- Timing: where the time went. A long Waiting for server response (also called TTFB, time to first byte) means a slow server. A long Content download means a big response or a slow network.
Toolbar features worth knowing
- Preserve log: keeps requests when the page reloads or redirects. Essential for login flows, payments and anything that navigates away.
- Disable cache: forces a fresh download of every file while DevTools is open. Use it to test what first-time visitors get, and to make sure you’re testing the latest buildBuildA specific compiled version of the app or website that is ready to be installed or tested.Open in glossary →.
- Throttling: the dropdown that says No throttling. Pick Fast 4G, Slow 4G, 3G or Offline to simulate poor connections (network throttlingNetwork throttlingDeliberately slowing the connection to test how an app behaves on poor networks.Open in glossary →). Watch for missing loading states, double submissions and timeouts.
- Filter by type: Fetch/XHR hides images and scripts so you only see API calls. The text box filters by URL, and supports properties like
status-code:500,method:POSTor-domain:*.analytics.com(the minus hides matches). - Copy as cURL: right-click a request → Copy → Copy as cURL. Developers can paste it into a terminal and replay the exact request. It also works in tools like postmanPostmanA popular tool for sending API requests and checking responses without using the app's UI.Open in glossary → (see API Testing with Postman).
- Export HAR: the download icon (↓) saves every request into a HAR fileHAR fileA file that records every network request and response a web page made.Open in glossary → (Chrome calls it Export HAR (sanitized)). Attach it to bug reports for complex problems.
Application: what the site remembers
The Application panel (called Storage in Firefox and Safari) shows what the site keeps in your browser:
- Cookies: small values sent with every request, like the session cookie that keeps you logged in. You can see each cookie’s expiry and security flags, and edit or delete it.
- Local storage: key/value data that survives closing the browser, e.g. a guest shopping cart or theme preference.
- Session storage: like local storage, but only for one tab, and gone when the tab closes.
- Storage › Clear site data: wipes everything for this site in one click. Perfect for testing as a “brand new visitor”.
Deleting a single cookie is a great test: delete the session cookie and click something. Does the site handle it gracefully (“Please log in again”) or crash? This panel gets a whole lesson of its own: Cookies, Sessions and Storage.
Device mode, Lighthouse and screenshots
Device mode (responsive testing)
Click the phone-and-tablet icon in the DevTools toolbar, or press Ctrl/Cmd+Shift+M. The page now renders in a phone-sized viewportViewportThe visible area of a web page in the browser window or on the device screen.Open in glossary →. From the toolbar above the page you can:
- Pick a device preset (iPhone, Pixel, iPad…) or choose Responsive and drag the edges to find the widths where the layout breaks (its breakpointsBreakpointA screen width where a responsive layout changes, for example from one column to two.Open in glossary →).
- Rotate to landscape, change zoom, and set the device pixel ratio.
- Simulate touch, so taps behave like on a phone.
Device mode is perfect for fast responsive designResponsive designA website layout that adapts to different screen sizes, from phones to large monitors.Open in glossary → checks (see Responsive Design Testing). But it’s still desktop Chrome pretending: it uses Chrome’s engine (not iOS Safari’s), your computer’s CPU, and no real keyboard, notch or browser toolbars. Always confirm important findings on a real deviceReal deviceA physical phone or tablet used for testing, as opposed to an emulator or simulator.Open in glossary →.
Lighthouse
The Lighthouse panel runs an automatic audit and scores the page from 0 to 100 in Performance, Accessibility, Best Practices and SEO. It also lists concrete problems: images without alt text, low contrast ratioContrast ratioHow different text and background colors are; WCAG asks for at least 4.5:1 for normal text.Open in glossary →, huge images, slow Core Web VitalsCore Web VitalsGoogle's key page experience metrics: loading (LCP), responsiveness (INP) and visual stability (CLS).Open in glossary →.
Use lighthouseLighthouseA free tool in Chrome DevTools that audits a page's performance, accessibility, SEO and best practices.Open in glossary → as a quick health check, not a verdict (more in Performance Basics and Accessibility Basics). Run it in an Incognito window (extensions skew the results), run it more than once (scores vary a few points), and remember that a perfect accessibility score doesn’t mean the site is accessible. It only catches what a machine can detect.
Screenshots without extra tools
Open the Command Menu (Ctrl/Cmd+Shift+P), type screenshot, and choose:
- Capture full size screenshot: the whole page, top to bottom, even the parts you’d have to scroll to. Brilliant for layout bugs on long pages.
- Capture node screenshot: just the element selected in Elements.
- Capture area screenshot: drag to select a region.
- Capture screenshot: the visible part only.
In device mode, the same options appear in the ⋮ menu of the device toolbar, so you can capture a page exactly at phone width.
Debugging a website on a real phone
Some bugs only happen on a real phone: Safari-only layout issues, the on-screen keyboard covering a button, touch problems. You can still use desktop DevTools by connecting the phone with a cable.
- Enable Developer options on the phone. Settings › About phone › tap Build number seven times.
- Turn on USB debugging. Settings › System › Developer options › USB debugging (the exact path varies by manufacturer).
- Connect the phone with a USB cable and accept the “Allow USB debugging?” prompt on the phone.
- On your computer, open Chrome and go to
chrome://inspect#devices. Your phone and its open Chrome tabs appear. - Click Inspect under the tab you want. A full DevTools window opens, with a live mirror of the phone screen.
Everything works as on desktop: Console errors, Network requests and throttling, Application storage, all for the real phone browser.
- On the iPhone, enable Web Inspector. Settings › Apps › Safari › Advanced › Web Inspector (on older iOS versions: Settings › Safari › Advanced).
- On the Mac, enable Safari’s developer features (Safari › Settings › Advanced › Show features for web developers).
- Connect the iPhone with a cable and tap Trust if asked.
- Open the website in Safari on the iPhone.
- On the Mac, open Safari’s Develop menu › your iPhone’s name › the page. Web Inspector opens and controls the page on the phone.
This also works for the iOS Simulator that comes with Xcode: it appears in the same Develop menu, no cable needed.
What to check with DevTools
Make these part of testing every web feature, not just when something looks broken:
- Console: clear it before an action. After the action, are there new red errors?
- Network status codes: does every API call your action triggers return 2xx? Does the page message match the status (no “Saved!” on a 500)?
- Duplicate and missing requests: does one click send exactly one request? Fast double-clicks are a classic way to create duplicate orders (double submitDouble submitA bug where an action runs twice because the user tapped or clicked twice quickly.Open in glossary →).
- Response data: is the data correct and complete? Is anything exposed that shouldn’t be (password hashes, other users’ data, internal notes, tokens)? That’s a security testingSecurity testingChecking that data and features are protected from unauthorized access and attacks.Open in glossary → finding.
- Performance: any request over ~1 s? Any huge images or scripts? What happens on Slow 4G and Offline?
- Broken resources: filter for
status-code:404. Missing images, fonts and scripts often go unnoticed on fast machines. - Storage: what’s saved in cookies and local storage? Is it cleared on logout?
- Layout: long text via Elements, phone widths via device mode, focus styles via :hov.
Common bugs DevTools reveal
| # | Bug | What you see | Typical severity |
|---|---|---|---|
| 1 | False success | The page says “Saved” but the request returned 4xx/5xx | High |
| 2 | JavaScript error on an action | A red TypeError in the Console, and the button or filter does nothing | High |
| 3 | Duplicate requests | The same API call fires twice per action, sometimes creating duplicates | Medium–High |
| 4 | Broken image or file | A red 404 row; a broken image icon or missing icon font on the page | Low–Medium |
| 5 | Data leak in a response | JSON includes fields like passwordHash, tokens or other users’ data | Critical |
| 6 | Slow endpoint | One request takes several seconds, mostly “Waiting for server response” | Medium |
| 7 | Wrong request data | The payload sends the old value, the wrong ID or a missing field | High |
| 8 | No loading or error state | On Slow 4G or Offline, the page freezes or shows nothing at all | Medium |
| 9 | Stale cache | The fix only appears with Disable cache on; regular users still get the old file | Medium |
| 10 | Sensitive data in the URL | A password, token or email appears in a request URL (and ends up in logs and history) | High |
Find the bug
Same shop, different build, and this one has six bugs. Some of them you can’t see on the page at all. Use every panel:
- Watch the Console while you click each filter.
- Change your display name, press Save, then reload.
- Look at every row in Network: status, how many times it appears, time, and the response of
me. - Wait for the whole page to finish loading.
🐞 Bug hunt: FreshCart deals page
This demo has 6 hidden bugs. Explore it like a tester, then check your findings.
Weekly deals
Prices valid until Sunday
Recommended for you
Tip: double-click a text node (or use the pencil) to edit it live.
}
- 1
Hint: Change your display name, press Save, and compare the toast with the Network panel. Then reload.
- 2
Hint: Click each filter chip with the Console open.
- 3
Hint: Count the products rows in Network after a reload or a filter click.
- 4
Hint: One product image looks different. Filter the Network panel by Img, or type status-code:404.
- 5
Hint: Open the Response tab of every API call, not just the failing ones.
- 6
Hint: Watch the "Recommended for you" section and sort out which request is slowest.
Notice the traceId in the response: many APIs return one. Copy it into your report, because developers can use it to find the exact error in the server logs.
A DevTools routine for every test session
- Open DevTools before you start, docked at the bottom. Open the Network panel and keep the Console’s error count in view.
- Tick Preserve log and Disable cache so you keep evidence across redirects and always test the latest files.
- Clear the Console and Network log before each important action (🚫). Then every new line belongs to your step.
- Do the action once, slowly. Check: new red errors? Status codes? One request or two? Payload and response correct?
- Repeat under stress: Slow 4G, Offline, a phone width in device mode, long text via Elements.
- Collect evidence when you find a bug: a screenshot (Command Menu › Capture screenshot), the console error text, the request URL, status, payload and response, and if needed a HAR file or cURL command.
Then write it up using the structure from How to Write Bug Reports.
Example test cases
TC-DT-001Saving the profile shows success only when the server succeedspositivehigh
Preconditions
- Logged in as maya@example.com
- DevTools open on the Network panel
Steps
- Change Display name to "Maya K"
- Click Save
- Check the PUT /api/profile row
- Reload the page
Expected result
PUT /api/profile returns 200. The "Profile saved" toast appears. After reload the header still shows "Maya K".
TC-DT-002Validation errors from the API are shown to the usernegativemedium
Preconditions
- Logged in
- DevTools open on the Network panel
Steps
- Clear the Display name field
- Click Save
Expected result
The request returns 422 with a validation error. The page shows "Please enter a display name." next to the field, and no success toast.
TC-DT-003Each filter click sends exactly one API request without console errorspositivemedium
Preconditions
- DevTools open
- Network filtered to Fetch/XHR
- Console cleared
Steps
- Click each filter chip in turn: All, Fruit, Bakery, On sale
Expected result
Each click creates exactly one GET /api/products request with the matching category and status 200. The product list updates. No errors appear in the Console.
TC-DT-004API responses contain no sensitive fieldsnegativehigh
Preconditions
- Logged in
- DevTools open on the Network panel
Steps
- Reload the page
- Open the Response tab of every fetch request (me, products, recommendations)
Expected result
No response contains password hashes, tokens, internal notes, IP addresses or another user's data.
TC-DT-005All page resources load without 404spositivelow
Preconditions
- DevTools open
- Disable cache ticked
Steps
- Reload the page
- Type status-code:404 in the Network filter
- Clear the filter and click the Status column header to sort, then look for any 5xx rows
Expected result
No request returns 404 or 5xx. All product images are visible.
TC-DT-006Page shows loading and error states on a poor connectionedgemedium
Preconditions
- DevTools open
- Throttling set to Slow 4G
Steps
- Reload the page and observe
- Switch throttling to Offline
- Click a filter chip
Expected result
On Slow 4G, skeletons are shown until data arrives and nothing is clickable twice by accident. Offline, the page shows a clear "You seem to be offline" message instead of freezing.
TC-DT-007Long product names do not break the card layoutedgelow
Steps
- Inspect the first product title (h3.card-title)
- Double-click its text and replace it with a 90-character name
- Check the card at desktop width and in device mode at 375 px
Expected result
The name is limited to two lines with an ellipsis. The price and Add button stay visible and aligned.
Tip: click a test case to expand it.
Checklist
DevTools test checklist
0 of 15 checked
Check your understanding
Quick quiz
0/5 answered · 0 correct
1.After clicking "Pay", the page shows "Payment successful", but the Network panel shows POST /api/payments with status 500. What is the best description?
2.Your login redirects to another page, and the request you wanted to inspect disappears from the Network panel. What should you turn on?
3.A request takes 6 seconds. The Timing tab shows 5.8 s of "Waiting for server response". Where is the problem most likely?
4.Which finding is a security bug even though nothing looks wrong on the page?
5.Why is device mode not enough on its own for mobile web testing?
Key takeaways
- Open DevTools with F12 or Cmd+Option+I. In Safari, switch on Show features for web developers first.
- Elements: inspect, edit text to test long content, check CSS, force
:hoverand:focus. Edits are temporary. - Console: red errors that appear right when an action fails usually explain why. Copy the message, file and line.
- Network: check status codes, count requests, read payloads and responses, check timing. Use Preserve log, Disable cache, throttling, Fetch/XHR, Copy as cURL and HAR export.
- Application: see and delete cookies and storage, or clear site data to test as a new visitor.
- Use device mode, Lighthouse and full-size screenshots for quick checks, and remote debugging to inspect real phones.
- The best DevTools bugs are the invisible ones: false successes, duplicate requests, data leaks and slow endpoints.
Finished this page?Nice work, this page is complete!
Mark it as done to track your progress. It's saved in this browser, no account needed.
Its review cards are now in Bites ⚡