Web Application Testing
Purpose
Verify a web application by driving it, systematically. Automated tests confirm what someone thought to check; interactive testing finds what nobody thought of, which is where the interesting bugs are.
When to Use
- Verifying a feature works before shipping.
- Reproducing a reported bug.
- Exploring a flow for defects that automated tests would not catch.
- Checking a fix in a real browser.
Capabilities
- Systematic exploration of a feature's state space.
- Console and network inspection during the flow.
- Boundary and error-path probing.
- Cross-viewport and cross-browser checks.
- Clear, reproducible defect reports.
Inputs
- The feature or flow, and what it is meant to do.
- The environment and any test credentials.
- The bug report, if reproducing.
Outputs
- A verdict: works, or a list of defects.
- For each defect: steps, expected, actual, evidence (screenshot, console error, failing request).
- Notes on what was checked, so gaps are visible.
Workflow
- Walk the happy path first — Confirm the feature does what it claims for a normal user with normal data. If this fails, stop; there is nothing else to test yet.
- Open the console and the network tab before you start — A 500 that the UI silently swallows, or a console error on every keystroke, is invisible if you are only looking at the page.
- Probe the boundaries — Empty input, maximum length, special characters, a name with an apostrophe, a quantity of zero, a quantity of -1. The interesting bugs live here.
- Break the network — Throttle it, then take it offline mid-request. What does the user see? A spinner forever is a defect.
- Test the back button and refresh — Mid-flow. Multi-step forms and payment flows break here constantly.
- Check the second viewport — At least one mobile width. Layouts break at breakpoints, and nobody looks.
Best Practices
- The console is the cheapest bug detector available and the least used. An error there during a flow that "works" is a defect that has not surfaced yet.
- Test what happens when the user does the reasonable-but-unexpected thing: double-clicking submit, opening two tabs, pressing back after paying.
- A defect report without steps to reproduce is a complaint. Include the exact input, the exact URL, and the exact browser.
- Check the network tab for requests that should not be there: an API called four times on one page load, a request firing on every keystroke without debouncing.
- Verify against the requirement, not against your assumption about the requirement. Read what it was supposed to do.
- Note what you did not test. An untested area that is assumed tested is worse than a known gap.
Examples
A systematic pass over one feature:
Feature: refund an order (admin)
Happy path
[PASS] Full refund on a paid order succeeds; the order shows "Refunded".
[PASS] Partial refund reduces the balance and shows the remaining amount.
Boundaries
[PASS] Refund of 0 is rejected with a clear message.
[FAIL] Refund exceeding the order total is accepted by the UI. The API
returns 422, but the UI shows a success toast and the row does not
update. The user believes the refund succeeded.
Steps: order ord_01HX (total $42) -> Refund -> enter 500 -> Submit.
Expected: an inline error stating the maximum refundable amount.
Actual: green "Refund issued" toast; no state change.
Console: POST /refunds 422 (Unprocessable Content) — error swallowed
in the .catch() at RefundModal.tsx:88.
Error paths
[FAIL] With the network offline, Submit spins indefinitely. No timeout, no
error state. The user cannot tell whether the money moved.
Interaction
[FAIL] Double-clicking Submit issues two POSTs. The second returns 409
(idempotency held), so no double refund occurs — but the UI shows
an unexplained error on the second response. The button is not
disabled during the request.
Not tested
- Multi-currency orders (no test data available in this environment).
- Refunds on orders older than 90 days (gateway restriction; needs a stub).
Three real defects, none of which an automated test suite was checking for, and all found in under fifteen minutes by being systematic rather than clever.
Notes
- The "success toast on a failed request" bug is extremely common and is invisible to anyone not watching the network tab. It is the strongest argument for having devtools open the entire time.
- A submit button that is not disabled during its request will be double-clicked by a real user, and the idempotency key is what saves you. Verify both the button and the key.
- When you find a defect worth keeping, write the automated test for it. Interactive testing finds bugs; automation stops them coming back.
1---2name: web-app-testing3description: Use when testing a web application interactively — verifying a feature, reproducing a bug, or checking a flow in a real browser. Covers systematic exploration, console and network inspection, and reporting what you find.4---56# Web Application Testing78## Purpose910Verify a web application by driving it, systematically. Automated tests confirm what someone thought to check; interactive testing finds what nobody thought of, which is where the interesting bugs are.1112## When to Use1314- Verifying a feature works before shipping.15- Reproducing a reported bug.16- Exploring a flow for defects that automated tests would not catch.17- Checking a fix in a real browser.1819## Capabilities2021- Systematic exploration of a feature's state space.22- Console and network inspection during the flow.23- Boundary and error-path probing.24- Cross-viewport and cross-browser checks.25- Clear, reproducible defect reports.2627## Inputs2829- The feature or flow, and what it is meant to do.30- The environment and any test credentials.31- The bug report, if reproducing.3233## Outputs3435- A verdict: works, or a list of defects.36- For each defect: steps, expected, actual, evidence (screenshot, console error, failing request).37- Notes on what was checked, so gaps are visible.3839## Workflow40411. **Walk the happy path first** — Confirm the feature does what it claims for a normal user with normal data. If this fails, stop; there is nothing else to test yet.422. **Open the console and the network tab before you start** — A 500 that the UI silently swallows, or a console error on every keystroke, is invisible if you are only looking at the page.433. **Probe the boundaries** — Empty input, maximum length, special characters, a name with an apostrophe, a quantity of zero, a quantity of -1. The interesting bugs live here.444. **Break the network** — Throttle it, then take it offline mid-request. What does the user see? A spinner forever is a defect.455. **Test the back button and refresh** — Mid-flow. Multi-step forms and payment flows break here constantly.466. **Check the second viewport** — At least one mobile width. Layouts break at breakpoints, and nobody looks.4748## Best Practices4950- The console is the cheapest bug detector available and the least used. An error there during a flow that "works" is a defect that has not surfaced yet.51- Test what happens when the user does the reasonable-but-unexpected thing: double-clicking submit, opening two tabs, pressing back after paying.52- A defect report without steps to reproduce is a complaint. Include the exact input, the exact URL, and the exact browser.53- Check the network tab for requests that should not be there: an API called four times on one page load, a request firing on every keystroke without debouncing.54- Verify against the requirement, not against your assumption about the requirement. Read what it was supposed to do.55- Note what you did *not* test. An untested area that is assumed tested is worse than a known gap.5657## Examples5859**A systematic pass over one feature:**6061```text62Feature: refund an order (admin)6364Happy path65 [PASS] Full refund on a paid order succeeds; the order shows "Refunded".66 [PASS] Partial refund reduces the balance and shows the remaining amount.6768Boundaries69 [PASS] Refund of 0 is rejected with a clear message.70 [FAIL] Refund exceeding the order total is accepted by the UI. The API71 returns 422, but the UI shows a success toast and the row does not72 update. The user believes the refund succeeded.73 Steps: order ord_01HX (total $42) -> Refund -> enter 500 -> Submit.74 Expected: an inline error stating the maximum refundable amount.75 Actual: green "Refund issued" toast; no state change.76 Console: POST /refunds 422 (Unprocessable Content) — error swallowed77 in the .catch() at RefundModal.tsx:88.7879Error paths80 [FAIL] With the network offline, Submit spins indefinitely. No timeout, no81 error state. The user cannot tell whether the money moved.8283Interaction84 [FAIL] Double-clicking Submit issues two POSTs. The second returns 40985 (idempotency held), so no double refund occurs — but the UI shows86 an unexplained error on the second response. The button is not87 disabled during the request.8889Not tested90 - Multi-currency orders (no test data available in this environment).91 - Refunds on orders older than 90 days (gateway restriction; needs a stub).92```9394Three real defects, none of which an automated test suite was checking for, and all found in under fifteen minutes by being systematic rather than clever.9596## Notes9798- The "success toast on a failed request" bug is extremely common and is invisible to anyone not watching the network tab. It is the strongest argument for having devtools open the entire time.99- A submit button that is not disabled during its request will be double-clicked by a real user, and the idempotency key is what saves you. Verify both the button and the key.100- When you find a defect worth keeping, write the automated test for it. Interactive testing finds bugs; automation stops them coming back.