Irwin
Irwin

Reputation: 422

How can I make Selenium click through a variable number of "next" buttons?

I have an internal web application that has a modal dialog. Unfortunately I cannot post the actual web application location here, but let me describe this as best as possible.

I'm able to click through a fixed number of times (ex: if I know there's two pages I can click twice) but I am unsure how to vary this so that it'll run no matter what number of pages I have. I would like a general solution; presumably this uses a loop of some sort that would check if the button is enabled. If it is, then click it. If it's disabled, then exit the loop.

The question is: How can I set up a loop in Selenium that clicks a button repeatedly until it is disabled?

Here's the code I've tried:

from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0

# Create a new instance of the Firefox driver
driver = webdriver.Firefox()

driver.get("http://localhost/myapp")

try:
    wait = WebDriverWait(driver, 100)    
    wait.until(EC.element_to_be_clickable((By.ID,'menuIntroBox_buttonNext')))    
    driver.find_element_by_id("menuIntroBox_buttonNext").click()

    # Click through the introduction text... this is the problematic code.
    # Here I tried to wait for the element to be clickable, then tried to do a while 
    # loop so I can click on it as long as it's clickable, but it never seems to do the
    # break.
    wait.until(EC.element_to_be_clickable((By.ID,'main_buttonMissionTextNext')))
    while EC.element_to_be_clickable((By.ID,'main_buttonMissionTextNext')):
        element = driver.find_element_by_id("main_buttonMissionTextNext")
        element.click()
        print "Waiting until it's clickable."

        if not element.is_enabled():
            break

    print "Here is where I'd do other stuff.... the stuff I want to actually do in the test case."
finally:
    driver.quit()

Upvotes: 8

Views: 6360

Answers (2)

e1che
e1che

Reputation: 1251

While driver.find_element_by_id("main_buttonMissionTextNext").isEnabled() {
  driver.find_element_by_id("main_buttonMissionTextNext").click();
  sleep(1);
}

//sleep function is in java, so you can "translate" it in python 
void sleep(int i){
  driver.manage().timeouts().implicitlyWait(i, TimeUnit.SECONDS);
}

try it and tell me what's up.

Upvotes: 0

Irwin
Irwin

Reputation: 422

Figured it out. Here's the relevant code block:

wait.until(EC.element_to_be_clickable((By.ID, 'main_buttonMissionTextNext')))
while EC.element_to_be_clickable((By.ID,'main_buttonMissionTextNext')):
    driver.find_element_by_id("main_buttonMissionTextNext").click()
    if not driver.find_element_by_id("main_buttonMissionTextNext").click().is_enabled():
        break
    wait.until(EC.element_to_be_clickable((By.ID, 'main_buttonMissionTextNext')))

Two things I found out:

  1. You can check if an element is enabled using is_enabled().
  2. You have to re-search the DOM for the element after clicking on it. I'm guessing that the dialog redraws itself, so you need to find it again.

I can likely refactor this to look nicer but the basic idea is here now.

Upvotes: 2

Related Questions