How to fill and submit a form with Selenium

Form tests become meaningful when the browser enters the intended values through user-facing controls and the application returns a state that confirms acceptance. Selenium can exercise that complete interaction instead of assigning values with JavaScript or treating a button click as proof that submission succeeded.

The Python example uses the public Selenium web form, so the locators, text entry, submit action, and response check can be reproduced without an application account. An explicit wait keeps each interaction tied to a visible or clickable state rather than an arbitrary time.sleep() delay.

The submit action uses the form's button because clicking it follows the same validation and event path as a user. Adapt the URL, locators, test values, and accepted response to the application under test, but keep both the filled-value assertions and the post-submit check.

Steps to fill and submit a form with Selenium:

  1. Create selenium-form-fill-submit.py with the WebDriver session and explicit wait.
    selenium-form-fill-submit.py
    import shutil
    from urllib.parse import urlparse
     
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.ui import WebDriverWait
     
     
    driver_path = shutil.which("chromedriver")
    service = Service(driver_path) if driver_path else Service()
     
    with webdriver.Chrome(service=service) as driver:
        wait = WebDriverWait(driver, 10)
        driver.get("https://www.selenium.dev/selenium/web/web-form.html")
  2. Append the text-field locators and input section inside the with block.
    selenium-form-fill-submit.py
        text_box = wait.until(
            EC.visibility_of_element_located((By.NAME, "my-text"))
        )
        text_area = driver.find_element(By.NAME, "my-textarea")
     
        text_box.clear()
        text_box.send_keys("Aisha Rahman")
        text_area.clear()
        text_area.send_keys("Please send the invoice.")
     
        filled_text = text_box.get_attribute("value")
        filled_area = text_area.get_attribute("value")
        assert filled_text == "Aisha Rahman"
        assert filled_area == "Please send the invoice."

    clear() prevents default, remembered, or server-rendered text from contaminating the entered value. A field reference captured before an application redraw can become stale.
    Related: How to troubleshoot stale element errors in Selenium

  3. Append the clickable submit-button section inside the with block.
    selenium-form-fill-submit.py
        submit_button = wait.until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, "button"))
        )
        submit_button.click()

    The user-facing submit button follows the browser validation and application event path.
    Related: How to click a button with Selenium

  4. Append the response assertions and observed-value output inside the with block.
    selenium-form-fill-submit.py
        message = wait.until(
            EC.visibility_of_element_located((By.ID, "message"))
        )
        submitted_path = urlparse(driver.current_url).path
        assert message.text == "Received!"
        assert submitted_path.endswith("/submitted-form.html")
     
        print(f"filled: {filled_text} | {filled_area}")
        print(f"message: {message.text}")
        print(f"path: {submitted_path}")

    A confirmation element or redirected URL should belong specifically to the accepted submission state. A click that leaves the original form unchanged must fail the test.

  5. Review the completed file against the assembled form workflow.
    selenium-form-fill-submit.py
    import shutil
    from urllib.parse import urlparse
     
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.ui import WebDriverWait
     
     
    driver_path = shutil.which("chromedriver")
    service = Service(driver_path) if driver_path else Service()
     
    with webdriver.Chrome(service=service) as driver:
        wait = WebDriverWait(driver, 10)
        driver.get("https://www.selenium.dev/selenium/web/web-form.html")
     
        text_box = wait.until(
            EC.visibility_of_element_located((By.NAME, "my-text"))
        )
        text_area = driver.find_element(By.NAME, "my-textarea")
     
        text_box.clear()
        text_box.send_keys("Aisha Rahman")
        text_area.clear()
        text_area.send_keys("Please send the invoice.")
     
        filled_text = text_box.get_attribute("value")
        filled_area = text_area.get_attribute("value")
        assert filled_text == "Aisha Rahman"
        assert filled_area == "Please send the invoice."
     
        submit_button = wait.until(
            EC.element_to_be_clickable((By.CSS_SELECTOR, "button"))
        )
        submit_button.click()
     
        message = wait.until(
            EC.visibility_of_element_located((By.ID, "message"))
        )
        submitted_path = urlparse(driver.current_url).path
        assert message.text == "Received!"
        assert submitted_path.endswith("/submitted-form.html")
     
        print(f"filled: {filled_text} | {filled_area}")
        print(f"message: {message.text}")
        print(f"path: {submitted_path}")
  6. Run the completed script to prove the values were entered and the form was accepted.
    $ python3 selenium-form-fill-submit.py
    filled: Aisha Rahman | Please send the invoice.
    message: Received!
    path: /selenium/web/submitted-form.html