Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions py/selenium/webdriver/remote/locator_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium.common.exceptions import InvalidSelectorException
from selenium.webdriver.common.by import By


Expand All @@ -23,6 +25,8 @@ def convert(self, by, value):
if by == By.ID:
return By.CSS_SELECTOR, f'[id="{value}"]'
elif by == By.CLASS_NAME:
if value and any(char.isspace() for char in value.strip()):
raise InvalidSelectorException("Compound class names are not allowed.")
return By.CSS_SELECTOR, f".{value}"
elif by == By.NAME:
return By.CSS_SELECTOR, f'[name="{value}"]'
Expand Down
5 changes: 5 additions & 0 deletions py/selenium/webdriver/remote/shadowroot.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

from hashlib import md5 as md5_hash

from selenium.common.exceptions import InvalidSelectorException
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.command import Command

Expand Down Expand Up @@ -74,6 +75,8 @@ def find_element(self, by: str = By.ID, value: str = None):
by = By.CSS_SELECTOR
value = f'[id="{value}"]'
elif by == By.CLASS_NAME:
if value and any(char.isspace() for char in value.strip()):
raise InvalidSelectorException("Compound class names are not allowed.")
by = By.CSS_SELECTOR
value = f".{value}"
elif by == By.NAME:
Expand Down Expand Up @@ -112,6 +115,8 @@ def find_elements(self, by: str = By.ID, value: str = None):
by = By.CSS_SELECTOR
value = f'[id="{value}"]'
elif by == By.CLASS_NAME:
if value and any(char.isspace() for char in value.strip()):
raise InvalidSelectorException("Compound class names are not allowed.")
by = By.CSS_SELECTOR
value = f".{value}"
elif by == By.NAME:
Expand Down
1 change: 1 addition & 0 deletions py/selenium/webdriver/remote/webdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

"""The WebDriver implementation."""

import base64
Expand Down
76 changes: 20 additions & 56 deletions py/test/selenium/webdriver/common/driver_element_finding_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from selenium.common.exceptions import InvalidSelectorException, NoSuchElementException
from selenium.webdriver.common.by import By

# By.id positive
# By.ID positive


def test_should_be_able_to_find_asingle_element_by_id(driver, pages):
Expand Down Expand Up @@ -53,7 +53,7 @@ def test_should_be_able_to_find_multiple_elements_by_numeric_id(driver, pages):
assert len(elements) == 8


# By.id negative
# By.ID negative


def test_should_not_be_able_to_locate_by_id_asingle_element_that_does_not_exist(driver, pages):
Expand Down Expand Up @@ -99,7 +99,7 @@ def test_no_such_element_error(driver, pages):
driver.find_element(By.ID, "non_Existent_Button")


# By.name positive
# By.NAME positive


def test_should_be_able_to_find_asingle_element_by_name(driver, pages):
Expand All @@ -120,7 +120,7 @@ def test_should_be_able_to_find_an_element_that_does_not_support_the_name_proper
assert element.get_attribute("name") == "div1"


# By.name negative
# By.NAME negative


def test_should_not_be_able_to_locate_by_name_asingle_element_that_does_not_exist(driver, pages):
Expand Down Expand Up @@ -159,7 +159,7 @@ def test_finding_multiple_elements_by_name_with_space_should_return_empty_list(d
assert len(elements) == 0


# By.tag_Name positive
# By.TAG_NAME positive


def test_should_be_able_to_find_asingle_element_by_tag_name(driver, pages):
Expand All @@ -174,7 +174,7 @@ def test_should_be_able_to_find_multiple_elements_by_tag_name(driver, pages):
assert len(elements) > 1


# By.tag_Name negative
# By.TAG_NAME negative


def test_should_not_be_able_to_locate_by_tag_name_asingle_element_that_does_not_exist(driver, pages):
Expand All @@ -189,22 +189,18 @@ def test_should_not_be_able_to_locate_by_tag_name_multiple_elements_that_do_not_
assert len(elements) == 0


@pytest.mark.xfail_firefox(reason="https://github.com/mozilla/geckodriver/issues/2007")
@pytest.mark.xfail_remote(reason="https://github.com/mozilla/geckodriver/issues/2007")
@pytest.mark.xfail_firefox(reason="unlike chrome, firefox raises NoSuchElementException")
@pytest.mark.xfail_remote(reason="unlike chrome, firefox raises NoSuchElementException")
@pytest.mark.xfail_safari(reason="unlike chrome, safari raises NoSuchElementException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_finding_asingle_element_by_empty_tag_name_should_throw(driver, pages):
pages.load("formPage.html")
with pytest.raises(InvalidSelectorException):
driver.find_element(By.TAG_NAME, "")


@pytest.mark.xfail_firefox(reason="https://github.com/mozilla/geckodriver/issues/2007")
@pytest.mark.xfail_remote(reason="https://github.com/mozilla/geckodriver/issues/2007")
@pytest.mark.xfail_firefox(reason="unlike chrome, firefox returns an empty list")
@pytest.mark.xfail_remote(reason="unlike chrome, firefox returns an empty list")
@pytest.mark.xfail_safari(reason="unlike chrome, safari returns an empty list")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_finding_multiple_elements_by_empty_tag_name_should_throw(driver, pages):
pages.load("formPage.html")
with pytest.raises(InvalidSelectorException):
Expand All @@ -223,7 +219,7 @@ def test_finding_multiple_elements_by_tag_name_with_space_should_return_empty_li
assert len(elements) == 0


# By.class_Name positive
# By.CLASS_NAME positive


def test_should_be_able_to_find_asingle_element_by_class(driver, pages):
Expand Down Expand Up @@ -269,7 +265,7 @@ def test_should_find_elements_by_class_when_its_name_is_surrounded_by_whitespace
assert elements[0].text == "Spaced out"


# By.class_Name negative
# By.CLASS_NAME negative


def test_should_not_find_element_by_class_when_the_name_queried_is_shorter_than_candidate_name(driver, pages):
Expand All @@ -279,8 +275,6 @@ def test_should_not_find_element_by_class_when_the_name_queried_is_shorter_than_


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_finding_asingle_element_by_empty_class_name_should_throw(driver, pages):
pages.load("xhtmlTest.html")
msg = r"\/errors#invalidselectorexception"
Expand All @@ -289,8 +283,6 @@ def test_finding_asingle_element_by_empty_class_name_should_throw(driver, pages)


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_finding_multiple_elements_by_empty_class_name_should_throw(driver, pages):
pages.load("xhtmlTest.html")
with pytest.raises(InvalidSelectorException):
Expand All @@ -299,29 +291,25 @@ def test_finding_multiple_elements_by_empty_class_name_should_throw(driver, page

def test_finding_asingle_element_by_compound_class_name_should_throw(driver, pages):
pages.load("xhtmlTest.html")
with pytest.raises(NoSuchElementException):
with pytest.raises(InvalidSelectorException):
driver.find_element(By.CLASS_NAME, "a b")


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_finding_asingle_element_by_invalid_class_name_should_throw(driver, pages):
pages.load("xhtmlTest.html")
with pytest.raises(InvalidSelectorException):
driver.find_element(By.CLASS_NAME, "!@#$%^&*")


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_finding_multiple_elements_by_invalid_class_name_should_throw(driver, pages):
pages.load("xhtmlTest.html")
with pytest.raises(InvalidSelectorException):
driver.find_elements(By.CLASS_NAME, "!@#$%^&*")


# By.xpath positive
# By.XPATH positive


def test_should_be_able_to_find_asingle_element_by_xpath(driver, pages):
Expand Down Expand Up @@ -388,7 +376,7 @@ def test_should_be_able_to_find_element_by_xpath_in_xml_document(driver, pages):
assert "baz" in element.text


# By.xpath negative
# By.XPATH negative


def test_should_throw_an_exception_when_there_is_no_link_to_click(driver, pages):
Expand All @@ -398,8 +386,6 @@ def test_should_throw_an_exception_when_there_is_no_link_to_click(driver, pages)


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_invalid_in_driver_find_element(
driver, pages
):
Expand All @@ -409,8 +395,6 @@ def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_inv


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_invalid_in_driver_find_elements(
driver, pages
):
Expand All @@ -420,8 +404,6 @@ def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_inv


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_invalid_in_element_find_element(
driver, pages
):
Expand All @@ -432,8 +414,6 @@ def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_inv


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_invalid_in_element_find_elements(
driver, pages
):
Expand All @@ -444,26 +424,20 @@ def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_inv


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_should_throw_invalid_selector_exception_when_xpath_returns_wrong_type_in_driver_find_element(driver, pages):
pages.load("formPage.html")
with pytest.raises(InvalidSelectorException):
driver.find_element(By.XPATH, "count(//input)")


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_should_throw_invalid_selector_exception_when_xpath_returns_wrong_type_in_driver_find_elements(driver, pages):
pages.load("formPage.html")
with pytest.raises(InvalidSelectorException):
driver.find_elements(By.XPATH, "count(//input)")


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_should_throw_invalid_selector_exception_when_xpath_returns_wrong_type_in_element_find_element(driver, pages):
pages.load("formPage.html")
body = driver.find_element(By.TAG_NAME, "body")
Expand All @@ -472,16 +446,14 @@ def test_should_throw_invalid_selector_exception_when_xpath_returns_wrong_type_i


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_should_throw_invalid_selector_exception_when_xpath_returns_wrong_type_in_element_find_elements(driver, pages):
pages.load("formPage.html")
body = driver.find_element(By.TAG_NAME, "body")
with pytest.raises(InvalidSelectorException):
body.find_elements(By.XPATH, "count(//input)")


# By.css_Selector positive
# By.CSS_SELECTOR positive


def test_should_be_able_to_find_asingle_element_by_css_selector(driver, pages):
Expand Down Expand Up @@ -530,7 +502,7 @@ def test_should_be_able_to_find_an_element_by_boolean_attribute_using_short_css_
assert element.get_attribute("value") == "two"


# By.css_Selector negative
# By.CSS_SELECTOR negative


def test_should_not_find_element_by_css_selector_when_there_is_no_such_element(driver, pages):
Expand All @@ -546,42 +518,34 @@ def test_should_not_find_elements_by_css_selector_when_there_is_no_such_element(


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_finding_asingle_element_by_empty_css_selector_should_throw(driver, pages):
pages.load("xhtmlTest.html")
with pytest.raises(InvalidSelectorException):
driver.find_element(By.CSS_SELECTOR, "")


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_finding_multiple_elements_by_empty_css_selector_should_throw(driver, pages):
pages.load("xhtmlTest.html")
with pytest.raises(InvalidSelectorException):
driver.find_elements(By.CSS_SELECTOR, "")


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_finding_asingle_element_by_invalid_css_selector_should_throw(driver, pages):
pages.load("xhtmlTest.html")
with pytest.raises(InvalidSelectorException):
driver.find_element(By.CSS_SELECTOR, "//a/b/c[@id='1']")


@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
def test_finding_multiple_elements_by_invalid_css_selector_should_throw(driver, pages):
pages.load("xhtmlTest.html")
with pytest.raises(InvalidSelectorException):
driver.find_elements(By.CSS_SELECTOR, "//a/b/c[@id='1']")


# By.link_Text positive
# By.LINK_TEXT positive


def test_should_be_able_to_find_alink_by_text(driver, pages):
Expand Down Expand Up @@ -632,7 +596,7 @@ def test_driver_can_get_link_by_link_test_ignoring_trailing_whitespace(driver, p
assert link.text == "link with trailing space"


# By.link_Text negative
# By.LINK_TEXT negative


def test_should_not_be_able_to_locate_by_link_text_asingle_element_that_does_not_exist(driver, pages):
Expand All @@ -647,7 +611,7 @@ def test_should_not_be_able_to_locate_by_link_text_multiple_elements_that_do_not
assert len(elements) == 0


# By.partial_Link_Text positive
# By.PARTIAL_LINK_TEXT positive


def test_should_be_able_to_find_multiple_elements_by_partial_link_text(driver, pages):
Expand Down