Forms Are Where Bugs Live

Forms are the primary way users interact with web applications — login, registration, search, checkout, profile updates, contact forms. They are also where the most bugs live. Every form field is an entry point for invalid data, unexpected characters, and edge cases.

A thorough form tester does not just fill in valid data and click submit. They think about every possible input a user — or an attacker — might provide.

Anatomy of a Web Form

A typical form includes:

  • Text inputs: Names, emails, addresses, free text
  • Selectors: Dropdowns, radio buttons, checkboxes
  • Special inputs: Date pickers, file uploads, color pickers, range sliders
  • Buttons: Submit, reset, cancel
  • Hidden fields: CSRF tokens, user IDs, tracking data

Each element type has its own class of bugs and test cases.

Client-Side vs. Server-Side Validation

Client-Side Validation

Happens in the browser using HTML attributes and JavaScript. It provides instant feedback but can be bypassed.

HTML validation attributes:

<input type="email" required minlength="5" maxlength="255" pattern="[a-z@.]+">

JavaScript validation:

if (password.length < 8) {
  showError('Password must be at least 8 characters');
  return false;
}

Server-Side Validation

Happens on the server after form submission. This is the security boundary — it cannot be bypassed by the user.

Critical testing rule: Always test server-side validation by bypassing client-side validation. In DevTools Console:

document.querySelector('form').noValidate = true;
// Or remove 'required' attributes:
document.querySelectorAll('[required]').forEach(el => el.removeAttribute('required'));

Then submit the form with invalid data. The server must still reject it.

Test Cases by Field Type

Text Fields

Test CaseInputExpected Result
Empty required field(nothing)Validation error
Minimum length1 characterAccept or reject per spec
Maximum lengthMax + 1 charactersReject or truncate
Special characters<script>alert('xss')</script>Sanitized, no script execution
Unicode characters名前 Ñoño ÜnïcödëAccept if international names supported
Leading/trailing spacesJohnAccept but trim, or reject per spec
Only spacesReject (empty after trimming)
Very long input10,000+ charactersHandle gracefully, no crash
SQL injection'; DROP TABLE users; --Safely handled, no SQL execution
HTML entities&amp; &lt; &#39;Displayed correctly
EmojisJohn 🎉 DoeAccept or reject consistently
Numbers in name fieldJohn123Per specification
Null bytesJohn\0DoeHandle safely

Email Fields

Test CaseInputExpected
Valid emailuser@example.comAccept
Missing @userexample.comReject
Missing domainuser@Reject
Missing local part@example.comReject
Double dotsuser@example..comReject
Subdomainuser@mail.example.comAccept
Plus addressinguser+tag@example.comAccept
Very long email255+ charactersPer RFC limit
International domainuser@例え.jpPer spec
Case sensitivityUser@EXAMPLE.COMAccept (emails are case-insensitive in domain)

Password Fields

Test CaseInputExpected
Minimum length7 chars (if min is 8)Reject with message
Maximum lengthVery long (1000+ chars)Accept or enforce max
No uppercasepassword123!Per policy
No numberPassword!!!Per policy
No special charPassword123Per policy
Common passwordspassword123, 123456Reject if blocklist exists
Spaces in passwordMy Password 1!Accept (spaces are valid)
Paste disabled?(Paste from clipboard)Should allow paste
Show/hide toggle(Click eye icon)Reveals/hides text

Numeric Fields

Test boundaries carefully: minimum value, maximum value, min-1, max+1, zero, negative numbers, decimal numbers, non-numeric characters.

Form Submission Testing

Submit Button States

  • Before interaction: Submit should be enabled (or disabled if specific fields are required)
  • During submission: Button should be disabled to prevent double submission; show loading indicator
  • After success: Redirect or show success message; form may clear
  • After failure: Show error messages; preserve user input; re-enable submit button

Double Submission

Click the submit button rapidly multiple times. Does the form:

  • Submit only once? (Correct)
  • Submit multiple times, creating duplicate records? (Bug)
  • Show a loading state that prevents re-clicking? (Good UX)

Advanced Form Testing

Tab Order and Keyboard Navigation

  1. Click in the first field and press Tab repeatedly
  2. Verify focus moves through fields in a logical order
  3. Verify you can submit the form using Enter
  4. Verify dropdown menus can be navigated with arrow keys
  5. Verify checkboxes toggle with Space
  6. Verify radio buttons switch with arrow keys

Autofill Testing

Browsers auto-fill forms using saved data. Test:

  • Does the form accept autofilled values correctly?
  • Are field names semantic enough for browsers to autofill appropriately? (name="email", name="given-name", etc.)
  • Does autofill trigger client-side validation?
  • Does the form break if autofill provides unexpected values?

Error Message Quality

Good error messages are:

  • Specific: “Email must include an @ symbol” not “Invalid input”
  • Located near the field: Inline errors, not just a list at the top
  • Persistent: Remain visible until the error is fixed
  • Accessible: Screen readers can announce them (use aria-describedby)
  • Non-blaming: “Please enter a valid email” not “You entered an invalid email”

Multi-Step Form Testing

Wizard-style forms with multiple steps need additional testing:

  • Can you navigate back to previous steps without losing data?
  • Does validation happen per step or only at the end?
  • What happens if you refresh mid-wizard?
  • If you open the URL in a new tab, does it start from step 1 or remember progress?
  • Can you deep-link to step 3 directly?

Exercise: Complete Form Audit

Find a registration or checkout form and test it using this checklist:

  1. Required fields: Submit the form with each required field empty, one at a time
  2. Boundary values: Test minimum and maximum lengths for every text field
  3. Special characters: Enter <script>alert(1)</script> in every field
  4. SQL injection: Enter ' OR 1=1 -- in every field
  5. Server-side validation: Bypass client-side validation in DevTools and resubmit
  6. Double submission: Click submit 5 times rapidly
  7. Tab order: Navigate the entire form with keyboard only
  8. Error messages: Trigger every validation error and document the message quality
  9. Autofill: Let the browser autofill and verify correctness
  10. Back button: Submit successfully, then press the browser back button

Document each finding:

FieldTestResultBug?
EmailSQL injection ' OR 1=1 --Server returns 500 errorYes - Critical
Name1000 charactersAccepted, but breaks profile layoutYes - Medium
PasswordPaste disabledCannot paste passwordYes - UX issue
AllDouble submitTwo accounts createdYes - Critical

Pro Tips

Tip 1: Test form submission with network throttling. Slow connections expose timing bugs like double submission.

Tip 2: Check what the server actually receives. In the Network tab, inspect the request payload — the data sent might differ from what was displayed.

Tip 3: Test required field indicators. If a field shows a red asterisk (*), it must actually be required. Sometimes the visual indicator and the validation logic get out of sync.

Key Takeaways

  • Forms are the highest-bug-density area of web applications
  • Always test both client-side and server-side validation independently
  • Boundary values, special characters, and empty fields are where most bugs hide
  • Double submission prevention must be tested on every form
  • Keyboard navigation and tab order affect both usability and accessibility
  • Error messages should be specific, well-positioned, and accessible
  • Bypassing client-side validation to test server-side is a critical security testing technique