Reputation: 399
So I am trying to fill out a form on this site. Every time I try to click the submit button at the end, using what I believe is the correct id, it just gives me an error. Here is a code snippet:
from selenium import webdriver
thePassword = "asdf123"
print("Desired name: ")
name = raw_input()
print("Desired Last Name: ")
userLastName = raw_input()
browser = webdriver.Firefox()
browser.get('https://www.panerabread.com/en-us/mypanera/registration-page.html')
firstName = browser.find_element_by_id('join_first_name')
firstName.send_keys(name)
lastName = browser.find_element_by_id('join_last_name')
lastName.send_keys(userLastName)
emailElem = browser.find_element_by_id('join_email')
emailElem.send_keys("asdafasda" + "@gmail.com")
emailConfirm = browser.find_element_by_id("join_confirm_email")
emailConfirm.send_keys("asdafasda" + "@gmail.com")
password = browser.find_element_by_id("join_password")
password.send_keys("thePassword")
passwordConfirm = browser.find_element_by_id("join_confirm_password")
passwordConfirm.send_keys("thePassword")
phoneA = browser.find_element_by_id("phone_number_a")
phoneA.send_keys("231")
phoneB = browser.find_element_by_id("phone_number_b")
phoneB.send_keys("123")
phoneC = browser.find_element_by_id("phone_number_c")
phoneC.send_keys("2310")
tos = browser.find_element_by_id("join_i_agree")
tos.click()
browser.execute_script("$('#join_password').get(0).scrollIntoView();")
#browser.implicitly_wait(10)
# And then perform the click
browser.find_element_by_id("join_card_not_available").click()
browser.find_elements_by_css_selector("#join-now-primary")[1].click()
print "Your email is: " + "asdafasda" + "@gmail.com"
print "Your password is: " + thePassword
My question is, how can I submit the form at the end of my script?
Edit: There is no error. The problem is that it doesn't click the button I want it to at all. I tried running the below code on a seperate file and it worked, however when you run it with this entire script it does not work.
Upvotes: 1
Views: 85
Reputation: 25552
This was a weird one... it took me a minute to figure out what was going on. The problem is that there are actually two elements that have that id on the page (which is a no-no according to the HTML standard... but alas it happens). One on the bottom of the page that you are looking at and another on the Sign In popup. If you click the Sign In button at the top of the page, you will see the (first) Sign In button on the popup. Because it is hidden, your code wouldn't click on it. Anyway... to the solution.
There are a few ways you can handle this, any of them valid. I would do this.
browser.find_elements_by_css_selector("#join-now-primary")[1].click()
What this is doing is using a CSS selector to get all the elements with ID=join-now-primary
. The CSS selector is #join-now-primary
which means id (#) of join-now-primary
. Because it uses .find_elements
(plural), it will get both. We then use [1]
to get the 2nd element (0-based index, so 1 is the 2nd) and then click on it.
EDIT
My guess is that it's a timing issue that is causing the code to work on its own but not in your script. Put a breakpoint on the first line and step through each line and make sure that it executes. Does it work? If I were to guess again... it's likely the line right before the Join Now click. That click has an animation that closes the credit card picture. I would wait for that section to become invisible using the code below
element = WebDriverWait(browser, 5).until(EC.invisibility_of_element_located(By.ID('panera-card-section')))
browser.find_elements_by_css_selector("#join-now-primary")[1].click()
Upvotes: 1
Reputation: 12782
You didn't really ask a question but it's likely you need to look at the WebElement class's methods and properties. Looks like the button might not be in the visible portion of the window based on your code. WebElement Has a property call that scrolls until an element moves into view.
If an element is not visible by Selenium definition, it is not clickable.
Even though you use the guts of the page to drive it, selenium wants to pretend it is testing human like interaction and so provides an artificial constraint.
You can bypass that by executing JavaScript click() on the element.
Upvotes: 0