Compound Class Names Are Not Supported Error in Webdriver

Compound class names not permitted error Webdriver

You can access the element if it has multiple classes using "By":

from selenium.webdriver.common.by import By
driver.findElement(By.cssSelector(".alert.alert-success"));

Invalid selector: Compound class names not permitted error using Selenium

As per the documentation of selenium.webdriver.common.by implementation:

class selenium.webdriver.common.by.By
Set of supported locator strategies.

CLASS_NAME = 'class name'

So,

  • Using find_element_by_class_name() you won't be able to pass multiple class names.
    Passing multiple classes you will face the error as:

    Message: invalid selector: Compound class names not permitted
  • Additionally, as you want to return an array of the chats, so instead of find_element* you need to use find_elements*


Solution

As an alternative you can use either of :the following Locator Strategies:

  • CSS_SELECTOR:

    recived_msg = driver.find_elements_by_css_selector(".XELVh.selectable-text.invisible-space.copyable-text")
  • XPATH:

    recived_msg = driver.find_elements_by_xpath("//*[@class='XELVh selectable-text invisible-space copyable-text']")

Selenium Compound class names not permitted

Leon's comment leads to the correct information that compound class names are no longer supported. What you could do instead is try using css selectors. In your case, the following line of code should help you get the element you want :

el3 = driver.find_element_by_css_selector(".action-btn.cancel.alert-display")

It finds the element with all three classes (action-btn, cancel and alert-display) in the class attribute. Do note that the order of the classes does not matter here and any of the classes may appear anywhere in the class attribute. As long as the element has all three classes, it will be selected.
If you want the order of the classes to be fixed, you can use the following xpath :

el3 = driver.find_element_by_xpath("//*[@class='action-btn cancel alert-display']") 

How to avoid Compound Class name error in Page Object?

Use a CSS selector instead:

.country.name

The important thing to note is that this example is wrong! If "country name" is meant as a name of a country, that is. Class names can't have spaces in them. In fact, the class attribute is a space-separated list of classes. That means that if you have a class country name, it's not one class, it's two different classes your element belongs to - the first is country, the second is name!

Therefore, fix your classes, if they're wrong. If they're not, use a CSS selector, it's the only reliable way to match multiple classes (apart from a very long and complicated XPath expression). Don't use trivial XPath expressions or CSS selectors with naive attribute comparison (//*[@class='country name'] or *[class='country name']), that's just plain wrong.

InvalidSelector Error: compound class names not permitted using FindElementByClass

You need to take care of a couple of things here:

  • The classnames of the <span> looks dynamic and and may change sooner or later, even may be next time you access the application afresh.
  • Selenium doesn't permit compund class names


Solution

To identify the element you can use the following locator strategies:

  • Using FindElementByCss:

    bot.FindElementByCss("span[title='Customer']")
  • Using FindElementByXPath:

    bot.FindElementByXPath("//span[@title='Customer' and text()='Customer']")

Compound class names are not supported. Consider searching for one class name and filtering the results

No, your own answer isn't the best one in terms of your question.

Imagine you have HTML like this:

<div class="bighead ght">LEAD DELIVERY MADE HARD</div>
<div class="bighead crb">LEAD DELIVERY MADE EASY</div>

driver.FindElement(By.ClassName("bighead")) will find both and return you the first div, instead of the one your want. What you really want is something like driver.FindElement(By.ClassName("bighead crb")), but like you said in your question, this won't work as you need another way to find elements by compound class names.

This why most people use more powerful By.CssSelector or By.XPath. Then you have:

CssSelector (the best):

driver.FindElement(By.CssSelector(".bighead.crb")); // flexible, match "bighead small crb", "bighead crb", "crb bighead", etc.
driver.FindElement(By.CssSelector("[class*='bighead crb']")); // order matters, match class contains "bighead crb"
driver.FindElement(By.CssSelector("[class='bighead crb']")); // match "bighead crb" strictly

XPath (the better):

driver.FindElement(By.XPath(".//*[contains(@class, 'bighead') and contains(@class, 'crb')]")); // flexible, match "bighead small crb", "bighead crb", "crb bighead", etc.
driver.FindElement(By.XPath(".//*[contains(@class, 'bighead crb')]")); // order matters, match class contains string "bighead crb" only
driver.FindElement(By.XPath(".//*[@class='bighead crb']")); // match class with string "bighead crb" strictly


Related Topics



Leave a reply



Submit