snub-fighter
snub-fighter

Reputation: 171

How to find and click on a button element that contains multiple classes

Using python + selenium chromedriver. At a login screen and trying to click the login button however I cant seem to identify the element properly.

Code trial:

login = driver.find_element_by_css_selector('tv-button.tv-button--no-border-radius.tv-button--size_large.tv-button--primary_ghost.tv-button--loader')
click(login)

HTML:

<button type="submit" class="tv-button tv-button--no-border-radius tv-button--size_large tv-button--primary_ghost tv-button--loader">
<span class="tv-button__text">Log In</span>
<span class="tv-button__loader"><span class="tv-button__loader-item"></span><span class="tv-button__loader-item"></span><span class="tv-button__loader-item"></span></span></button>

Upvotes: 2

Views: 2374

Answers (5)

undetected Selenium
undetected Selenium

Reputation: 193258

The element is a dynamic element so to locate and click on the element you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following solutions:

  • Using CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.tv-button--no-border-radius.tv-button--loader>span.tv-button__text"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@class='tv-button tv-button--no-border-radius tv-button--size_large tv-button--primary_ghost tv-button--loader']/span[@class='tv-button__text' and text()='Log In']"))).click()
    
  • 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
    

Upvotes: 0

KunduK
KunduK

Reputation: 33384

Try Induce WebDriverWait to identify the element and then click on that.

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

element=WebDriverWait(driver,30).until(EC.element_to_be_clickable((By.CSS_SELECTOR,'button.tv-button span')))
print(element.text)
element.click()

Upvotes: 0

QHarr
QHarr

Reputation: 84465

I would attempt a shorter class selector of

driver.find_element_by_css_selector('.tv-button').click()

Upvotes: 1

cruisepandey
cruisepandey

Reputation: 29362

No doubt that we should always choose css selector over xpath.

But the css selector you are using : .tv-button.tv-button--no-border-radius.tv-button--size_large.tv-button--primary_ghost.tv-button--loader looks very unstable.

For just login button, you could use :

xpath : //span[contains(text(),'Log In')]/parent::button

Reason behind that you should avoid css selector is that (in this case), that css selector is combination of class name, so in case if any class name changes, you will have to change the locator.

Probability of changing the class name in this case is highly likely. Cause it's made of 5 classes.

Hope this will helps.

Upvotes: 1

Huy Ngo
Huy Ngo

Reputation: 382

It seems you miss the . at beginning, so Css selector will look for tv-button tag instead of class. Try this:

login = driver.find_element_by_css_selector('.tv-button.tv-button--no-border-radius.tv-button--size_large.tv-button--primary_ghost.tv-button--loader')
click(login)

Upvotes: 1

Related Questions