Filling out forms Selenium

Question:

I’m trying to learn how to fill out forms using selenium. I am attempting to see if I can automate the process for demo requests for various different software companies, and was wondering if someone could help me.

Code:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
import time

options = webdriver.ChromeOptions()
options.add_argument("--no-sandbox")
options.add_argument("start-maximized")
options.add_argument('disable-notifications')
options.add_experimental_option("detach", True)
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()),options=options)
actions = ActionChains(driver)

url = 'https://pathable.com/request-demo/'
driver.get(url)

time.sleep(2)

first_name = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="firstname-a5e8be35-7e08-4485-a4d1-cd749e8ec5b5"]'))).click()
first_name.send_keys("Name 1")
time.sleep(2)
last_name = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="lastname-a5e8be35-7e08-4485-a4d1-cd749e8ec5b5"]'))).click()
last_name.send_keys("Name 2")
time.sleep(2)
company_name = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="company-a5e8be35-7e08-4485-a4d1-cd749e8ec5b5"]'))).click()
company_name.send_keys("Test Company")

driver.quit()

Error:

AttributeError: 'NoneType' object has no attribute 'send_keys'

Desired Forms inputs:

First name: Name 1
Last name: Name 2
Company name: Test Company
Email: [email protected]
Phone number: (111) 111-1111
Job Title: Test Title
Country: United States
State: North Carolina
Comments: Hello 
Asked By: BQuist

||

Answers:

Those long IDs appear to be generated dynamically, so they might change on page reload (or server restart, app restart etc). On top of this, page appears to react to user’s input, so you need to interact with it first, in order for that form to appear. The following is one way of interacting with the page, and filling out that form:

from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys

chrome_options = Options()
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument('disable-notifications')
chrome_options.add_argument("window-size=1280,720")

webdriver_service = Service("chromedriver/chromedriver") ## path to where you saved chromedriver binary
browser = webdriver.Chrome(service=webdriver_service, options=chrome_options)

url = 'https://pathable.com/request-demo/'
browser.get(url)
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[contains(text(), 'Use this form to contact us or call directly at')]"))).click()

WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='firstname']"))).send_keys('Soichiro')
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='lastname']"))).send_keys('Honda')
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='company']"))).send_keys('Honda')
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[@name='email']"))).send_keys('[email protected]')

Please observe the imports, as well as the part after defining the browser/driver (you might have a different selenium setup), and also, Selenium docs can be found at: https://www.selenium.dev/documentation/
EDIT: To select the country from the drop down menu, you can do:

Select(WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//select[@name='country_code']")))).select_by_visible_text('Japan') 
Answered By: platipus_on_fire

WebDriverWait(driver, 10).until(whatever))) returns a webElement object.
That’s why you can apply .click() or any other applicable method on it.
But when you are applying .click() on a webElement object this returns nothing, void, ‘NoneType’.
This is why

first_name = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="firstname-a5e8be35-7e08-4485-a4d1-cd749e8ec5b5"]'))).click()

assigns nothing, ‘NoneType’, into the first_name variable. So it is not a webElement type object and you can’t apply .click() method on it.
But you do can apply send_keys method on it directly, as following:

WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="firstname-a5e8be35-7e08-4485-a4d1-cd749e8ec5b5"]'))).send_keys("Name 1")

In this way you can send text to all those elements.

Answered By: Prophet
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.