How Browsers Work

When you type https://shop.example.com/products/42 and press Enter, the browser runs the chain of steps behind every page load: it asks DNS (the Domain Name System) for the server's IP address, the numeric address of the machine; opens a connection and encrypts it with TLS; sends an HTTP request and receives the response. Then it turns the HTML, CSS and JavaScript it received into pixels on the screen. The first half fetches bytes; the second half renders them.

For a tester this chain is a map. Every visible failure happens at one of its steps, and each step leaves evidence you can inspect in the browser itself.

Why it matters

"The site is broken" can mean a DNS record pointing at the wrong server, an expired certificate, a 500 response, a stylesheet that returned 404 or a JavaScript error that stopped a click handler. Each has a different owner and a different fix. A tester who knows the steps can say which one it is and attach the evidence, instead of filing a report nobody can act on.

The steps also show what to test. A page is dozens of requests and several stages of processing, and each can fail on its own: on a slow network, in another browser, or with an outdated cached file.

Fetching the page: from URL to response

The browser splits the address into scheme (https), host (shop.example.com), path, query and fragment; the fragment, such as #reviews, is never sent to the server. If the browser cache holds a fresh copy of the response, the browser may skip the network entirely. Otherwise the network steps run in order:

  • DNS lookup: the host name becomes an IP address, such as 203.0.113.10. Answers are cached, so a DNS change may not show at once. If the name does not resolve, the browser shows its own error page (in Chrome, DNS_PROBE_FINISHED_NXDOMAIN or ERR_NAME_NOT_RESOLVED) and no request reaches the server.
  • Connection: the browser opens a TCP connection, on port 443 for HTTPS, and keeps it open for later requests. HTTP/3 uses QUIC over UDP instead, which sets up the connection and the TLS encryption in one combined handshake.
  • TLS handshake: the browser and the server agree on encryption keys, and the browser checks that the server's certificate comes from a trusted authority, is in date and covers this host name. A failed check shows a full-page warning instead of the site, in Chrome with a code such as NET::ERR_CERT_DATE_INVALID.
  • HTTP request: a method and a path, such as GET /products/42, with headers like Host and User-Agent and the cookies stored for the site.
  • HTTP response: a status code such as 200, 404 or 500, headers like Content-Type (the kind of file, such as text/html) and Cache-Control, and a body. A redirect (301, 302) sends the browser back to the first step with the URL in its Location header.

Try it: URL Parser Try it: Redirect Checker

Building the page: HTML, CSS, JavaScript, render

The browser parses the HTML while it is still arriving: it decodes the bytes with the declared character set and builds the DOM, the tree of elements that scripts and test tools work with. The parser repairs broken markup silently, so bad HTML rarely shows an error. Every stylesheet, script, image and font the page refers to becomes another request, and any of them can fail while the page itself returns 200.

  • CSS: stylesheets in the <head> block rendering. The browser waits for them before the first paint, and if one fails, the page appears without its styles.
  • JavaScript: a plain <script src> pauses the parser until the script has run; defer waits until parsing ends, async runs on arrival. Scripts change the DOM, attach click handlers and request data. An uncaught error stops the code that was running, so a page can look complete while a button does nothing.
  • Render: the browser computes each element's style, lays out every box and paints the pixels. Later changes, such as an image without reserved space or a banner a script inserts, trigger layout and paint again, which is why content can jump.
  • Milestones: DOMContentLoaded fires when the HTML is parsed and deferred scripts have run; load fires when images, stylesheets and other resources have finished too.

What a tester can observe at each step

Browser developer tools (DevTools: F12 in Chrome, Edge and Firefox, or Cmd+Option+I on a Mac) show almost every step; a later lesson tours their panels. The Network panel lists one row per request with its status, type, size and timing, and its summary bar shows the DOMContentLoaded and load times. It records only while it is open, so open it first, then reload. It can export all rows as a HAR file (HTTP Archive), a JSON file that another person can open in their own DevTools.

A page load in nine steps: five fetch the bytes and four turn them into pixels, and every step leaves evidence a tester can check in the browser. Conceptual model
  1. Fetch: from the address to the response

    Repeats for every stylesheet, script, image and font the page needs

    1. 1Read the URLAddress bar; the request URL in the Network panelhttps://shop.example.com/products/42
    2. 2DNS lookupTiming: the DNS phaseshop.example.com → 203.0.113.10

      Branch: Name not resolved: the browser’s own error pageFail

    3. 3Connect: TCP, then TLSTiming: connecting and TLS; the certificate viewer

      Branch: Expired or wrong-name certificate: a full-page warningFail

    4. 4HTTP requestHeaders tab: method, URL, request headers, cookiesGET /products/42
    5. 5HTTP responseStatus column, response headers, Response tab200 OK · text/html

      Branch: 3xx redirect: back to step 1 with the Location URL

  2. Render: from bytes to pixels

    1. 6Parse HTML into the DOMPage source, Elements panel; every file it links starts a new fetch
    2. 7Apply CSSStylesheet rows; the first paint waits for them

      Branch: Stylesheet fails: the page shows without its stylesFail

    3. 8Run JavaScriptConsole; Fetch/XHR rows for data loaded later

      Branch: Uncaught error: a button that does nothingFail

    4. 9Style, layout, paintThe screen; DOMContentLoaded and load times

      Repeats: Runs again when the DOM, images or fonts change: content can jump

Simplified: rendering starts while bytes and files are still arriving, and open connections are reused. Each card says where a tester looks.

  • Before any request: DNS, connection and certificate failures show a code on the browser's own error page. No HTTP request was sent, so the server's access logs have no entry for it. The site-information icon at the left of the address bar opens the certificate, with its issuer and validity dates.
  • The Timing view of one request: phases such as DNS lookup, connecting, TLS, waiting for the server and downloading. The names vary slightly between browsers.
  • The Headers and Response tabs: what was sent (method, URL, headers, cookies) and what came back (status, headers, body). Chrome marks rows served from the cache as (disk cache) or (memory cache); the "Disable cache" checkbox makes reloads skip the browser cache while DevTools is open.
  • Page source and Elements: View page source (Ctrl+U on Windows) shows the HTML exactly as it arrived; the Elements panel (Inspector in Firefox) shows the DOM after the parser's repairs and the scripts' changes.
  • The Console: JavaScript errors and refused resources, with file and line. Rendering problems show only on the screen, so capture screenshots or a recording.

Try it: Request Header Inspector Try it: HTTP Headers Parser

Worked example: a product page without styles

After a release to staging, the test copy of the site where a release is checked before it reaches production, a tester opens https://staging.shop.example.com/products/42. Text and images appear, but in one plain column with default fonts. Walking the steps finds the cause in minutes:

  • The page appeared, so DNS, the connection and TLS worked. The document row is 200 and the text is readable, so the HTML arrived and was decoded correctly.
  • The row for app.3f9c1e.css is 404 with Content-Type: text/html: the server sent its "not found" page instead of the stylesheet, and the Console says the browser refused it because its MIME type, the file type named in Content-Type, is not text/css.
  • So the HTML refers to a CSS file the server does not have: either the file was not deployed or the HTML names the wrong file. It is a build or deployment defect, not a defect in the CSS code, and it affects every browser. The bug report carries the evidence:
Title:    Product page unstyled on staging: app.3f9c1e.css returns 404
URL:      https://staging.shop.example.com/products/42
Build:    web 2.14.0 on staging
Request:  GET https://staging.shop.example.com/assets/app.3f9c1e.css
Response: 404 Not Found, Content-Type: text/html; charset=utf-8
Console:  Refused to apply style from '.../assets/app.3f9c1e.css' because its
          MIME type ('text/html') is not a supported stylesheet MIME type,
          and strict MIME checking is enabled.
Expected: 200 with Content-Type: text/css
Evidence: screenshot; HAR file of a reload with the cache disabled

Try it: Content-Type Validator Try it: HTTP Status Code Lookup

Common mistakes

  • Reporting "the page does not load" without the step: a browser error page, an HTTP error status and a broken page after a 200 are different defects with different owners.
  • Testing only with a warm cache. Reload with the cache disabled, and check once in a new private window, which starts without your cookies and cached files.
  • Trusting the status code alone: a 200 can carry an error page.
  • Opening DevTools after the problem appeared, when the Network panel has recorded nothing, or never opening the Console at all.
  • Assuming every failure is in the application code. DNS, certificates, CDNs (content delivery networks, which serve copies of files from servers near the user) and caches fail too, and for DNS and certificate failures the server's access logs show nothing.

The QA perspective

Before filing, place the failure on a step: the browser's own error page (DNS, connection, TLS), the status of the document, a failed sub-request, a console error, or a rendering problem with everything loaded. That one decision tells the team who should look: whoever runs DNS and certificates, back-end or front-end developers, or the deployment pipeline.

Record the exact URL, the status and Content-Type of the failing request, the console message, the browser and its version, and whether the cache was disabled. A HAR file helps when several requests are involved, but it can contain cookies, tokens and personal data (Chrome leaves out cookie and authorization headers by default; other browsers may not), so remove secrets before attaching it. When the cause sits outside the page, ask early: "Are new asset files deployed before the HTML that uses them?"

Practice exercise

Place six symptoms on the page-load steps

Your task

You test a web shop at https://shop.example.com. For each observation below, name the page-load step where it fails and the evidence you would attach to the bug report.

Material
1. Only on the office network, the browser shows ERR_NAME_NOT_RESOLVED
   for shop.example.com.
2. A full-page warning says the connection is not private; the certificate
   expired yesterday.
3. /checkout shows the server's error page; the document row is 500.
4. The page looks right, but "Add to cart" does nothing. Console:
   Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
5. Arabic product names appear as "ال..." on every product page.
6. The price block jumps down when a promotional banner appears.
Steps
  1. Decide whether the browser got as far as sending an HTTP request.
  2. If it did, decide between the document response, a sub-request, HTML parsing, JavaScript and rendering.
  3. Write the step and the evidence for each observation.
Show the model answer
Model answer

1. DNS lookup: no request reached the server. Evidence: the error code, the network you were on, and the output of nslookup shop.example.com (a command that asks DNS for the address) on that network and on another.

2. TLS handshake. Evidence: the warning page with its error code (in Chrome, NET::ERR_CERT_DATE_INVALID), the certificate's validity dates, and the date and time of the test.

3. Document response: the request reached the server and failed there. Evidence: the method, URL, 500 status, response body and exact time, so a developer can find the log entry.

4. JavaScript: the script looked for an element that was not there (not yet in the DOM, or its id changed), so the click handler was never attached. Evidence: the full console message with file and line.

5. HTML parsing: UTF-8 bytes decoded with the wrong character set. Evidence: the Content-Type response header (does it say charset=utf-8?) and the <meta charset> in the page source. If both declare UTF-8, the names were already garbled on the server, for example in the database, and the defect belongs to the back end.

6. Render: the banner is inserted after the first paint without reserved space, so layout runs again. Evidence: a screen recording, the browser and the window size.

Frequently asked questions

Do I need to know networking to test web applications?

Not in depth. You need the order of the steps and what each one looks like when it fails, so you can place a problem and collect the right evidence. The HTTP module of the roadmap goes deeper into requests, responses, headers and caching.

Why does a page work for me but not for a colleague?

Some step differs between you: a different DNS answer (office network, VPN, a hosts file entry), a different cached copy, different cookies, another browser or an extension. Compare both Network panels; the first row that differs is a good place to start.

Is this the same in every browser?

The order is the same in Chrome, Edge, Firefox and Safari, because it follows shared standards: the WHATWG HTML and Fetch standards and the HTTP and TLS specifications. Error messages, DevTools names and timing details differ. More importantly, each browser engine (Blink in Chrome and Edge, Gecko in Firefox, WebKit in Safari) implements those standards with its own gaps and bugs, which is why cross-browser testing exists.

References

Practise with Mutqan tools

Break a URL into protocol, host, port, path, query parameters, fragment and credentials.

Web

Trace redirect chains (301/302/307/308) and see every hop, status and final URL.

Web

Inspect the request headers your browser or client sends, with explanations for each.

API Testing

Parse raw HTTP request/response headers into a structured table with explanations.

Web

Validate Content-Type headers and check that a response body actually matches its declared media type.

Web

Go deeper

Your progress on this topic

Part of the QA Roadmap