Skip to content

Commit 8cf970a

Browse files
committed
[py] Raise InvalidSelectorException for compound class names
1 parent 1bad7af commit 8cf970a

File tree

2 files changed

+26
-56
lines changed

2 files changed

+26
-56
lines changed

py/selenium/webdriver/remote/webdriver.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# KIND, either express or implied. See the License for the
1515
# specific language governing permissions and limitations
1616
# under the License.
17+
1718
"""The WebDriver implementation."""
1819

1920
import base64
@@ -33,6 +34,7 @@
3334

3435
from selenium.common.exceptions import (
3536
InvalidArgumentException,
37+
InvalidSelectorException,
3638
JavascriptException,
3739
NoSuchCookieException,
3840
NoSuchElementException,
@@ -915,6 +917,10 @@ def find_element(self, by=By.ID, value: Optional[str] = None) -> WebElement:
915917
WebElement
916918
The first matching `WebElement` found on the page.
917919
"""
920+
if by == "class name":
921+
if " " in value.strip():
922+
raise InvalidSelectorException("Compound class names are not allowed.")
923+
918924
by, value = self.locator_converter.convert(by, value)
919925

920926
if isinstance(by, RelativeBy):
@@ -951,6 +957,10 @@ def find_elements(self, by=By.ID, value: Optional[str] = None) -> list[WebElemen
951957
List[WebElement]
952958
list of `WebElements` matching locator strategy found on the page.
953959
"""
960+
if by == "class name":
961+
if " " in value.strip():
962+
raise InvalidSelectorException("Compound class names are not allowed.")
963+
954964
by, value = self.locator_converter.convert(by, value)
955965

956966
if isinstance(by, RelativeBy):

py/test/selenium/webdriver/common/driver_element_finding_tests.py

Lines changed: 16 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from selenium.common.exceptions import InvalidSelectorException, NoSuchElementException
2121
from selenium.webdriver.common.by import By
2222

23-
# By.id positive
23+
# By.ID positive
2424

2525

2626
def test_should_be_able_to_find_asingle_element_by_id(driver, pages):
@@ -53,7 +53,7 @@ def test_should_be_able_to_find_multiple_elements_by_numeric_id(driver, pages):
5353
assert len(elements) == 8
5454

5555

56-
# By.id negative
56+
# By.ID negative
5757

5858

5959
def test_should_not_be_able_to_locate_by_id_asingle_element_that_does_not_exist(driver, pages):
@@ -99,7 +99,7 @@ def test_no_such_element_error(driver, pages):
9999
driver.find_element(By.ID, "non_Existent_Button")
100100

101101

102-
# By.name positive
102+
# By.NAME positive
103103

104104

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

122122

123-
# By.name negative
123+
# By.NAME negative
124124

125125

126126
def test_should_not_be_able_to_locate_by_name_asingle_element_that_does_not_exist(driver, pages):
@@ -159,7 +159,7 @@ def test_finding_multiple_elements_by_name_with_space_should_return_empty_list(d
159159
assert len(elements) == 0
160160

161161

162-
# By.tag_Name positive
162+
# By.TAG_NAME positive
163163

164164

165165
def test_should_be_able_to_find_asingle_element_by_tag_name(driver, pages):
@@ -174,7 +174,7 @@ def test_should_be_able_to_find_multiple_elements_by_tag_name(driver, pages):
174174
assert len(elements) > 1
175175

176176

177-
# By.tag_Name negative
177+
# By.TAG_NAME negative
178178

179179

180180
def test_should_not_be_able_to_locate_by_tag_name_asingle_element_that_does_not_exist(driver, pages):
@@ -189,22 +189,14 @@ def test_should_not_be_able_to_locate_by_tag_name_multiple_elements_that_do_not_
189189
assert len(elements) == 0
190190

191191

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

202198

203-
@pytest.mark.xfail_firefox(reason="https://github.com/mozilla/geckodriver/issues/2007")
204-
@pytest.mark.xfail_remote(reason="https://github.com/mozilla/geckodriver/issues/2007")
205199
@pytest.mark.xfail_safari(reason="unlike chrome, safari returns an empty list")
206-
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
207-
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
208200
def test_finding_multiple_elements_by_empty_tag_name_should_throw(driver, pages):
209201
pages.load("formPage.html")
210202
with pytest.raises(InvalidSelectorException):
@@ -223,7 +215,7 @@ def test_finding_multiple_elements_by_tag_name_with_space_should_return_empty_li
223215
assert len(elements) == 0
224216

225217

226-
# By.class_Name positive
218+
# By.CLASS_NAME positive
227219

228220

229221
def test_should_be_able_to_find_asingle_element_by_class(driver, pages):
@@ -269,7 +261,7 @@ def test_should_find_elements_by_class_when_its_name_is_surrounded_by_whitespace
269261
assert elements[0].text == "Spaced out"
270262

271263

272-
# By.class_Name negative
264+
# By.CLASS_NAME negative
273265

274266

275267
def test_should_not_find_element_by_class_when_the_name_queried_is_shorter_than_candidate_name(driver, pages):
@@ -279,8 +271,6 @@ def test_should_not_find_element_by_class_when_the_name_queried_is_shorter_than_
279271

280272

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

290280

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

300288
def test_finding_asingle_element_by_compound_class_name_should_throw(driver, pages):
301289
pages.load("xhtmlTest.html")
302-
with pytest.raises(NoSuchElementException):
290+
with pytest.raises(InvalidSelectorException):
303291
driver.find_element(By.CLASS_NAME, "a b")
304292

305293

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

314300

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

323307

324-
# By.xpath positive
308+
# By.XPATH positive
325309

326310

327311
def test_should_be_able_to_find_asingle_element_by_xpath(driver, pages):
@@ -388,7 +372,7 @@ def test_should_be_able_to_find_element_by_xpath_in_xml_document(driver, pages):
388372
assert "baz" in element.text
389373

390374

391-
# By.xpath negative
375+
# By.XPATH negative
392376

393377

394378
def test_should_throw_an_exception_when_there_is_no_link_to_click(driver, pages):
@@ -398,8 +382,6 @@ def test_should_throw_an_exception_when_there_is_no_link_to_click(driver, pages)
398382

399383

400384
@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
401-
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
402-
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
403385
def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_invalid_in_driver_find_element(
404386
driver, pages
405387
):
@@ -409,8 +391,6 @@ def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_inv
409391

410392

411393
@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
412-
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
413-
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
414394
def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_invalid_in_driver_find_elements(
415395
driver, pages
416396
):
@@ -420,8 +400,6 @@ def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_inv
420400

421401

422402
@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
423-
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
424-
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
425403
def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_invalid_in_element_find_element(
426404
driver, pages
427405
):
@@ -432,8 +410,6 @@ def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_inv
432410

433411

434412
@pytest.mark.xfail_safari(reason="unlike chrome, safari raises TimeoutException")
435-
@pytest.mark.xfail_chrome(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
436-
@pytest.mark.xfail_edge(reason="https://bugs.chromium.org/p/chromedriver/issues/detail?id=4743")
437413
def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_invalid_in_element_find_elements(
438414
driver, pages
439415
):
@@ -444,26 +420,20 @@ def test_should_throw_invalid_selector_exception_when_xpath_is_syntactically_inv
444420

445421

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

454428

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

463435

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

473443

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

483451

484-
# By.css_Selector positive
452+
# By.CSS_SELECTOR positive
485453

486454

487455
def test_should_be_able_to_find_asingle_element_by_css_selector(driver, pages):
@@ -530,7 +498,7 @@ def test_should_be_able_to_find_an_element_by_boolean_attribute_using_short_css_
530498
assert element.get_attribute("value") == "two"
531499

532500

533-
# By.css_Selector negative
501+
# By.CSS_SELECTOR negative
534502

535503

536504
def test_should_not_find_element_by_css_selector_when_there_is_no_such_element(driver, pages):
@@ -546,42 +514,34 @@ def test_should_not_find_elements_by_css_selector_when_there_is_no_such_element(
546514

547515

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

556522

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

565529

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

574536

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

583543

584-
# By.link_Text positive
544+
# By.LINK_TEXT positive
585545

586546

587547
def test_should_be_able_to_find_alink_by_text(driver, pages):
@@ -632,7 +592,7 @@ def test_driver_can_get_link_by_link_test_ignoring_trailing_whitespace(driver, p
632592
assert link.text == "link with trailing space"
633593

634594

635-
# By.link_Text negative
595+
# By.LINK_TEXT negative
636596

637597

638598
def test_should_not_be_able_to_locate_by_link_text_asingle_element_that_does_not_exist(driver, pages):
@@ -647,7 +607,7 @@ def test_should_not_be_able_to_locate_by_link_text_multiple_elements_that_do_not
647607
assert len(elements) == 0
648608

649609

650-
# By.partial_Link_Text positive
610+
# By.PARTIAL_LINK_TEXT positive
651611

652612

653613
def test_should_be_able_to_find_multiple_elements_by_partial_link_text(driver, pages):

0 commit comments

Comments
 (0)