Finding a button with selenium in python

Question:

I am trying to create a web application that automately republishes on a site for private sales.

Login and everything went well, but if I try to find and click the republish button it just wont work.
I’ve tried it with every locator, but the problem is that every button got an uniqe ID.
Example:

<button name="republish" type="button" data-testid="5484xxxxx-republish-button" class="Button__ButtonContainer-sc-3uxxxx-0 hxXxxX">Republish</button>

The last I’ve tried:

buttons = driver.find_elements(By.XPATH, "//*[contains(text(), 'Republish')]")

for btn in buttons:
    btn.click()

But it also didnt work, same with By.NAME, BY.TAG_NAME

Asked By: nelloyo

||

Answers:

The <button> element looks to be dynamically generated so to click elements you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following locator strategies:

  • Using CSS_SELECTOR:

    driver.execute_script("arguments[0].click();", WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[data-testid$='republish-button'][name='republish']")))) 
    
  • Using XPATH:

    driver.execute_script("arguments[0].click();", WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[starts-with(@class, 'Button__ButtonContainer') and contains(@data-testid, 'republish-button')][@name='republish' and text()='Republish']"))))
    
  • Note: You have to add the following imports :

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
Answered By: undetected Selenium