David J.
David J.

Reputation: 1913

can't click button or submit form using Selenium

I'm trying to use Selenium w/ Python to click on answers to problems posted at a tutoring site, so I can take tests over the command line.

I enter the following:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
driver.get('https://www.varsitytutors.com/sat_critical_reading_diagnostic_1-problem-10821')

(an annoying popup comes up at this point -- we can ignore that for now)

Answers on the page are embedded in forms like this:

         <div class="question_row">    
            <form class="button_to" method="post" action="/problem_question_answers/save_answer?answer_id=539461&amp;problem_id=5065&amp;qotd=false&amp;question_id=10821">
            <input id="answer_539461" class="test_button" type="submit" value="select" /><input type="hidden" name="authenticity_token" value="LE4B973DghoAF6Ja2qJUPIajNXhPRjy6fCDeELqemIl5vEuvxhHUbkbWeDeLHvBMtEUVIr7okC8Njp4eMIuU3Q==" /></form>
            <div class="answer">
              <p>English dramatists refused to employ slang in their work.</p>
            </div>
            <div style="clear:both"></div>
          </div>

My goal is to click an answer such as this one in order to get to the next question using Selenium.

I thought it might be as easy as doing this:

answer_buttons=driver.find_elements_by_class_name('test_button')
answer_buttons[1].click()

But I get error messages saying that the element is out of the frame of the driver.

I've also tried submitting the form, which doesn't produce an error message:

answer_forms=driver.find_elements_by_class_name('button_to')
answer_forms[1].submit()

But it redirects to a different url that doesn't load: http://www.varsitytutors.com/sat_critical_reading_diagnostic_1-problems-results-d9399f1a-4e00-42a0-8867-91b1c8c9057d

Is there any way to do this programmatically, or is the website's code going to prevent this?

Edit:

With some help I was able to click the button once initially. But an identical submit button (by xpath) for the next question remains unclickable. This is the code I'm presently using:

driver.get('https://www.varsitytutors.com/practice-tests')

# click subject
subject=driver.find_element_by_xpath('/html/body/div[3]/div[9]/div/div[2]/div[1]/div[1]')
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[3]/div[9]/div/div[2]/div[1]/div[1]')))
subject.click()
# select specialty
specialty=driver.find_element_by_xpath('/html/body/div[3]/div[9]/div/div[2]/div[2]/div[1]/div[2]/a[4]')
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[3]/div[9]/div/div[2]/div[2]/div[1]/div[2]/a[4]')))
specialty.click()
# select test 
taketest=WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[3]/div[8]/div[3]/div[1]/div[1]/a[1]')))
driver.execute_script("arguments[0].click();", taketest)    

# click away popup
button=WebDriverWait(driver,5).until(EC.element_to_be_clickable((By.XPATH,"//button[contains(.,'No Thanks')]")))
button.location_once_scrolled_into_view
button.click()

# select first choice
choice=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[3]/div[7]/div[1]/div[3]/div[1]/form/input[1]')))
driver.execute_script("arguments[0].click();", choice)    

I repeat this code again over the next few lines. It has no effect, however; the drive stays on question two and the next few clicks don't work...

choice=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[3]/div[7]/div[1]/div[3]/div[1]/form/input[1]')))
driver.execute_script("arguments[0].click();", choice)
choice=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,'/html/body/div[3]/div[7]/div[1]/div[3]/div[1]/form/input[1]')))

driver.execute_script("arguments[0].click();", choice)

Upvotes: 0

Views: 642

Answers (1)

KunduK
KunduK

Reputation: 33384

Try the following code.This will handle pop-up and click on the select button.

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 import webdriver
driver=webdriver.Chrome()
driver.get('https://www.varsitytutors.com/sat_critical_reading_diagnostic_1-problem-10821')
driver.maximize_window()
button=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//button[contains(.,'No Thanks, Start The Test')]")))
button.location_once_scrolled_into_view
button.click()
eleQuestions=WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'input.test_button')))
driver.execute_script("arguments[0].click();", eleQuestions[2])

button=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//button[contains(.,'No Thanks')]")))
button.location_once_scrolled_into_view
button.click()

Please note: you can change the indexes from 2 to 6.

Snapshot:

enter image description here


If you would like to select any particular Question as you mentioned then try below code.

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 import webdriver
driver=webdriver.Chrome()
driver.get('https://www.varsitytutors.com/sat_critical_reading_diagnostic_1-problem-10821')
driver.maximize_window()
button=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//button[contains(.,'No Thanks, Start The Test')]")))
button.location_once_scrolled_into_view
button.click()
eleQuestions=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//div[./p[text()='English dramatists refused to employ slang in their work.']]/parent::div//input[1]")))
driver.execute_script("arguments[0].click();", eleQuestions)

button=WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//button[contains(.,'No Thanks')]")))
button.location_once_scrolled_into_view
button.click()

Upvotes: 1

Related Questions