SeleniumHQ / selenium

A browser automation framework and ecosystem.
https://selenium.dev
Apache License 2.0
30.72k stars 8.19k forks source link

By.classname works differently in Java and Python #9025

Closed praveendvd closed 3 years ago

praveendvd commented 3 years ago

🐛 Bug Report

in Python multiple classes can be found by replacing space with '.'

To Reproduce Python:

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"))

Java:

    ChromeDriver driver=new ChromeDriver();
driver.get("https://stackoverflow.com/questions/65579491/find-element-by-class-name-in-selenium-giving-error/65579606?noredirect=1#comment115946541_65579606");

    WebElement a = driver.findElementByClassName("overflow-x-auto.ml-auto.-secondary.grid.ai-center.list-reset.h100");
    System.out.print(a.getAttribute("outerHTML"));

Detailed steps to reproduce the behavior:

behavior

In python script works fine

In Java noELement exception is thrown: ( it seems the functions add frontslash to the locator

image

image

Expected behavior:

Both should work as same

Environment

OS: Browser:

Language Bindings version: Java and Python Selenium Grid version (if applicable):3.141.59

SalmonMode commented 3 years ago

Hey there!

You're right, both should behave the same. However, it's not my call to make which way should be the way. In the meantime though, I would suggest using a CSS selector instead (that's what it uses under the hood anyway).

diemol commented 3 years ago

@praveendvd, what versions of the language bindings are you using? What OS, what browser, and what browser version?

praveendvd commented 3 years ago

@praveendvd, what versions of the language bindings are you using? What OS, what browser, and what browser version?

Language Bindings version: javac 12.0.1 and Python 3.9.1 Selenium Grid version (if applicable):3.141.59

praveendvd commented 3 years ago

@praveendvd, what versions of the language bindings are you using? What OS, what browser, and what browser version?

if you investigate python selenium source code

 ```
 elif by == By.CLASS_NAME:
            by = By.CSS_SELECTOR
            value = ".%s" % value


its just replacing the entire string with a '.' infront. But in java it adds etc font slashes.

https://github.com/SeleniumHQ/selenium/blob/9160de55af9cc230f758f4ce6a2af8d1570f0614/py/selenium/webdriver/remote/webdriver.py
diemol commented 3 years ago

Java is escaping the locator, which is expected. If you'd prefer to treat the locator as it is, better use By.cssSelector.

What is important to notice is that when By.className("overflow-x-auto.ml-auto.-secondary.grid.ai-center.list-reset.h100") is used, you are expecting an element that looks lke <div class="overflow-x-auto.ml-auto.-secondary.grid.ai-center.list-reset.h100">, and on the provided link, there is no element with that class.

I understand that the locator worked for you with the Python bindings, but there might be small implementation differences between the language bindings, and seems you bumped into one. The important thing to realize here, is that the locator is more suited as a cssSelector.

If you have more questions or comments, please drop by our Slack/IRC channel where we can continue the conversation. Links for the channels can be seen here https://www.selenium.dev/support/

Thanks to @barancev, @shs96c and @AutomatedTester for helping to debug this.