-1

I am trying to automate a button click using selenium but it is giving me the error. The html code of the page is: enter image description here

The code i am trying is:

create_team=driver.find_element_by_class_name('ts-btn ts-btn-fluent ts-btn-fluent-secondary ts-btn-fluent-with-icon join-team-button')
create_team.click()

I am getting the following error:

enter image description here

Arpit
  • 394
  • 1
  • 11

3 Answers3

2

driver.find_element_by_class_name() only accepts one className, it's not built to handle multiple classNames, reference - (How to locate an element with multiple class names?), THIS SEEMS TO BE UP FOR DEBATE

Use driver.find_element_by_css_selector('ts-btn.ts-btn-fluent.ts-btn-fluent-secondary.ts-btn-fluent-with-icon.join-team-button')

With driver.find_element_by_css_selector you can chain multiple classNames together using a dot(.) between each className in the selector.

Ryan Wilson
  • 10,223
  • 2
  • 21
  • 40
  • Thats incorect statement you can find multiple class using class_name – PDHide Jan 05 '21 at 13:17
  • Oh? I don't see anything in the documentation saying you can use multiple classNames with that particular method, using CssSelector is the correct way to search on multiple classNames. – Ryan Wilson Jan 05 '21 at 13:17
  • jusyt have to replace space with '.' – PDHide Jan 05 '21 at 13:18
  • https://stackoverflow.com/a/65444957/6793637 can try out the example mentioned in this answer – PDHide Jan 05 '21 at 13:18
  • 1
    @PDHide If you look at this SO post it is accepted that the `find_element_by_class_name()` only accepts one className - (https://stackoverflow.com/questions/60534244/how-to-locate-an-element-with-multiple-class-names) – Ryan Wilson Jan 05 '21 at 13:20
  • 1
    @PDHide Every article I've looked up says that that method doesn't work with multiple. (https://www.nuomiphp.com/eplan/en/70157.html), (https://stackoverflow.com/questions/44759907/find-element-by-class-name-for-multiple-classes#:~:text=The%20answer%20is%20No%2C%20You,find_element_by_class_name%20()%20or%20driver.&text=It%20accepts%20only%20single%20class,element%20with%20multiple%20class%20names.) – Ryan Wilson Jan 05 '21 at 13:24
  • You can try out the example mentioned or can try out your self – PDHide Jan 05 '21 at 13:24
  • @PDHide Either way, my answer still gives the OP a working solution as CssSelector will work. Have you tried using it with `find_element_by_class_name`? (http://makeseleniumeasy.com/2017/09/26/how-to-locate-web-element-which-has-multiple-class-names/) – Ryan Wilson Jan 05 '21 at 13:24
  • see my updated answer , added the explanation and an working example from this question itself – PDHide Jan 05 '21 at 13:33
  • your answer mentioned an incorrect statement that we cannot use multiple class was just pointing that out :) – PDHide Jan 05 '21 at 13:37
0
create_team=driver.find_element_by_class_name('ts-btn.ts-btn-fluent.ts-btn-fluent-secondary ts-btn-fluent-with-icon.join-team-button')
create_team.click()

You have to replace space with . as space indicate multiple class

You can use xpath or css also:

create_team=driver.find_element_by_xpath("//*[@class='ts-btn.ts-btn-fluent.ts-btn-fluent-secondary ts-btn-fluent-with-icon.join-team-button]')
create_team.click()


create_team=driver.find_element_by_css_selector("[class='ts-btn.ts-btn-fluent.ts-btn-fluent-secondary ts-btn-fluent-with-icon.join-team-button]')
create_team.click()

More to answer

If you check the exception from the by_class_name:

enter image description here

You can see that it is using css_class locator under the hood ( You can see it add . in frontautomatically)

Working example:

from selenium import webdriver

import time

from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome()
driver.get("https://stackoverflow.com/questions/65579491/find-element-by-class-name-in-selenium-giving-error/65579606?noredirect=1#comment115946541_65579606")
time.sleep(5)
elem = driver.find_element_by_class_name('overflow-x-auto.ml-auto.-secondary.grid.ai-center.list-reset.h100')

print(elem.get_attribute("outerHTML"))
PDHide
  • 18,113
  • 2
  • 31
  • 46
0

To click on the element you can use either of the following Locator Strategies:

  • Using css_selector:

    driver.find_element_by_css_selector("button.ts-btn.ts-btn-fluent.ts-btn-fluent-secondary.ts-btn-fluent-with-icon.join-team-button[data-tid='tg-discover-team']").click()
    
  • Using xpath:

    driver.find_element_by_xpath("//button[@class='ts-btn ts-btn-fluent ts-btn-fluent-secondary ts-btn-fluent-with-icon join-team-button' and @data-tid='tg-discover-team']").click()
    

As the desired element is an Angular element, ideally to click on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:

  • Using CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.ts-btn.ts-btn-fluent.ts-btn-fluent-secondary.ts-btn-fluent-with-icon.join-team-button[data-tid='tg-discover-team']"))).click()
    
  • Using XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@class='ts-btn ts-btn-fluent ts-btn-fluent-secondary ts-btn-fluent-with-icon join-team-button' and @data-tid='tg-discover-team']"))).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
    
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352