Skip to content

Commit 25124be

Browse files
committed
Support RelativeBy in type annotations
1 parent 7425162 commit 25124be

File tree

4 files changed

+42
-24
lines changed

4 files changed

+42
-24
lines changed

Diff for: py/selenium/webdriver/remote/shadowroot.py

+15-5
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,15 @@
1616
# under the License.
1717

1818
from hashlib import md5 as md5_hash
19+
from typing import List
20+
from typing import Optional
21+
from typing import Union
1922

20-
from ..common.by import By
2123
from .command import Command
24+
from .webelement import WebElement
25+
from ..common.by import By
26+
from ..common.by import ByType
27+
from ..support.relative_locator import RelativeBy
2228

2329

2430
class ShadowRoot:
@@ -39,7 +45,8 @@ def __repr__(self) -> str:
3945
type(self), self.session.session_id, self._id
4046
)
4147

42-
def find_element(self, by: str = By.ID, value: str = None):
48+
def find_element(self, by: Union[ByType, RelativeBy] = By.ID,
49+
value: Optional[str] = None) -> WebElement:
4350
"""Find an element inside a shadow root given a By strategy and
4451
locator.
4552
@@ -76,9 +83,11 @@ def find_element(self, by: str = By.ID, value: str = None):
7683
by = By.CSS_SELECTOR
7784
value = f'[name="{value}"]'
7885

79-
return self._execute(Command.FIND_ELEMENT_FROM_SHADOW_ROOT, {"using": by, "value": value})["value"]
86+
return self._execute(Command.FIND_ELEMENT_FROM_SHADOW_ROOT, {"using": by, "value": value})[
87+
"value"]
8088

81-
def find_elements(self, by: str = By.ID, value: str = None):
89+
def find_elements(self, by: Union[ByType, RelativeBy] = By.ID, value: Optional[str] = None) -> \
90+
List[WebElement]:
8291
"""Find elements inside a shadow root given a By strategy and locator.
8392
8493
Parameters:
@@ -114,7 +123,8 @@ def find_elements(self, by: str = By.ID, value: str = None):
114123
by = By.CSS_SELECTOR
115124
value = f'[name="{value}"]'
116125

117-
return self._execute(Command.FIND_ELEMENTS_FROM_SHADOW_ROOT, {"using": by, "value": value})["value"]
126+
return self._execute(Command.FIND_ELEMENTS_FROM_SHADOW_ROOT, {"using": by, "value": value})[
127+
"value"]
118128

119129
# Private Methods
120130
def _execute(self, command, params=None):

Diff for: py/selenium/webdriver/remote/webdriver.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
from selenium.common.exceptions import WebDriverException
4444
from selenium.webdriver.common.bidi.script import Script
4545
from selenium.webdriver.common.by import By
46+
from selenium.webdriver.common.by import ByType
4647
from selenium.webdriver.common.options import ArgOptions
4748
from selenium.webdriver.common.options import BaseOptions
4849
from selenium.webdriver.common.print_page_options import PrintOptions
@@ -769,7 +770,7 @@ def timeouts(self, timeouts) -> None:
769770
"""
770771
_ = self.execute(Command.SET_TIMEOUTS, timeouts._to_json())["value"]
771772

772-
def find_element(self, by=By.ID, value: Optional[str] = None) -> WebElement:
773+
def find_element(self, by: Union[ByType, RelativeBy] = By.ID, value: Optional[str] = None) -> WebElement:
773774
"""Find an element given a By strategy and locator.
774775
775776
Parameters:
@@ -805,7 +806,7 @@ def find_element(self, by=By.ID, value: Optional[str] = None) -> WebElement:
805806

806807
return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"]
807808

808-
def find_elements(self, by=By.ID, value: Optional[str] = None) -> List[WebElement]:
809+
def find_elements(self, by: Union[ByType, RelativeBy] = By.ID, value: Optional[str] = None) -> List[WebElement]:
809810
"""Find elements given a By strategy and locator.
810811
811812
Parameters:

Diff for: py/selenium/webdriver/support/event_firing_webdriver.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,18 @@
1717

1818
from typing import Any
1919
from typing import List
20+
from typing import Optional
2021
from typing import Tuple
22+
from typing import Union
2123

2224
from selenium.common.exceptions import WebDriverException
2325
from selenium.webdriver.common.by import By
26+
from selenium.webdriver.common.by import ByType
2427
from selenium.webdriver.remote.webdriver import WebDriver
2528
from selenium.webdriver.remote.webelement import WebElement
2629

2730
from .abstract_event_listener import AbstractEventListener
31+
from .relative_locator import RelativeBy
2832

2933

3034
def _wrap_elements(result, ef_driver):
@@ -185,10 +189,10 @@ def clear(self) -> None:
185189
def send_keys(self, *value) -> None:
186190
self._dispatch("change_value_of", (self._webelement, self._driver), "send_keys", value)
187191

188-
def find_element(self, by=By.ID, value=None) -> WebElement:
192+
def find_element(self, by: Union[ByType, RelativeBy] = By.ID, value: Optional[str] = None) -> WebElement:
189193
return self._dispatch("find", (by, value, self._driver), "find_element", (by, value))
190194

191-
def find_elements(self, by=By.ID, value=None) -> List[WebElement]:
195+
def find_elements(self, by: Union[ByType, RelativeBy] = By.ID, value: Optional[str] = None) -> List[WebElement]:
192196
return self._dispatch("find", (by, value, self._driver), "find_elements", (by, value))
193197

194198
def _dispatch(self, l_call, l_args, d_call, d_args):

Diff for: py/selenium/webdriver/support/expected_conditions.py

+18-15
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,10 @@
3131
from selenium.common.exceptions import StaleElementReferenceException
3232
from selenium.common.exceptions import WebDriverException
3333
from selenium.webdriver.common.alert import Alert
34+
from selenium.webdriver.common.by import ByType
3435
from selenium.webdriver.remote.webdriver import WebDriver
3536
from selenium.webdriver.remote.webdriver import WebElement
37+
from selenium.webdriver.support.relative_locator import RelativeBy
3638

3739
"""
3840
* Canned "Expected Conditions" which are generally useful within webdriver
@@ -43,6 +45,7 @@
4345
T = TypeVar("T")
4446

4547
WebDriverOrWebElement = Union[WebDriver, WebElement]
48+
LocatorType = Union[Tuple[ByType, str], Tuple[RelativeBy, None]]
4649

4750

4851
def title_is(title: str) -> Callable[[WebDriver], bool]:
@@ -72,7 +75,7 @@ def _predicate(driver: WebDriver):
7275
return _predicate
7376

7477

75-
def presence_of_element_located(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], WebElement]:
78+
def presence_of_element_located(locator: LocatorType) -> Callable[[WebDriverOrWebElement], WebElement]:
7679
"""An expectation for checking that an element is present on the DOM of a
7780
page. This does not necessarily mean that the element is visible.
7881
@@ -141,7 +144,7 @@ def _predicate(driver: WebDriver):
141144

142145

143146
def visibility_of_element_located(
144-
locator: Tuple[str, str]
147+
locator: LocatorType
145148
) -> Callable[[WebDriverOrWebElement], Union[Literal[False], WebElement]]:
146149
"""An expectation for checking that an element is present on the DOM of a
147150
page and visible. Visibility means that the element is not only displayed
@@ -179,7 +182,7 @@ def _element_if_visible(element: WebElement, visibility: bool = True) -> Union[L
179182
return element if element.is_displayed() == visibility else False
180183

181184

182-
def presence_of_all_elements_located(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], List[WebElement]]:
185+
def presence_of_all_elements_located(locator: LocatorType) -> Callable[[WebDriverOrWebElement], List[WebElement]]:
183186
"""An expectation for checking that there is at least one element present
184187
on a web page.
185188
@@ -193,7 +196,7 @@ def _predicate(driver: WebDriverOrWebElement):
193196
return _predicate
194197

195198

196-
def visibility_of_any_elements_located(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], List[WebElement]]:
199+
def visibility_of_any_elements_located(locator: LocatorType) -> Callable[[WebDriverOrWebElement], List[WebElement]]:
197200
"""An expectation for checking that there is at least one element visible
198201
on a web page.
199202
@@ -208,7 +211,7 @@ def _predicate(driver: WebDriverOrWebElement):
208211

209212

210213
def visibility_of_all_elements_located(
211-
locator: Tuple[str, str]
214+
locator: LocatorType
212215
) -> Callable[[WebDriverOrWebElement], Union[List[WebElement], Literal[False]]]:
213216
"""An expectation for checking that all elements are present on the DOM of
214217
a page and visible. Visibility means that the elements are not only
@@ -231,7 +234,7 @@ def _predicate(driver: WebDriverOrWebElement):
231234
return _predicate
232235

233236

234-
def text_to_be_present_in_element(locator: Tuple[str, str], text_: str) -> Callable[[WebDriverOrWebElement], bool]:
237+
def text_to_be_present_in_element(locator: LocatorType, text_: str) -> Callable[[WebDriverOrWebElement], bool]:
235238
"""An expectation for checking if the given text is present in the
236239
specified element.
237240
@@ -249,7 +252,7 @@ def _predicate(driver: WebDriverOrWebElement):
249252

250253

251254
def text_to_be_present_in_element_value(
252-
locator: Tuple[str, str], text_: str
255+
locator: LocatorType, text_: str
253256
) -> Callable[[WebDriverOrWebElement], bool]:
254257
"""An expectation for checking if the given text is present in the
255258
element's value.
@@ -268,7 +271,7 @@ def _predicate(driver: WebDriverOrWebElement):
268271

269272

270273
def text_to_be_present_in_element_attribute(
271-
locator: Tuple[str, str], attribute_: str, text_: str
274+
locator: LocatorType, attribute_: str, text_: str
272275
) -> Callable[[WebDriverOrWebElement], bool]:
273276
"""An expectation for checking if the given text is present in the
274277
element's attribute.
@@ -288,7 +291,7 @@ def _predicate(driver: WebDriverOrWebElement):
288291
return _predicate
289292

290293

291-
def frame_to_be_available_and_switch_to_it(locator: Union[Tuple[str, str], str]) -> Callable[[WebDriver], bool]:
294+
def frame_to_be_available_and_switch_to_it(locator: Union[LocatorType, str]) -> Callable[[WebDriver], bool]:
292295
"""An expectation for checking whether the given frame is available to
293296
switch to.
294297
@@ -310,7 +313,7 @@ def _predicate(driver: WebDriver):
310313

311314

312315
def invisibility_of_element_located(
313-
locator: Union[WebElement, Tuple[str, str]]
316+
locator: Union[WebElement, LocatorType]
314317
) -> Callable[[WebDriverOrWebElement], Union[WebElement, bool]]:
315318
"""An Expectation for checking that an element is either invisible or not
316319
present on the DOM.
@@ -336,7 +339,7 @@ def _predicate(driver: WebDriverOrWebElement):
336339

337340

338341
def invisibility_of_element(
339-
element: Union[WebElement, Tuple[str, str]]
342+
element: Union[WebElement, LocatorType]
340343
) -> Callable[[WebDriverOrWebElement], Union[WebElement, bool]]:
341344
"""An Expectation for checking that an element is either invisible or not
342345
present on the DOM.
@@ -347,7 +350,7 @@ def invisibility_of_element(
347350

348351

349352
def element_to_be_clickable(
350-
mark: Union[WebElement, Tuple[str, str]]
353+
mark: Union[WebElement, LocatorType]
351354
) -> Callable[[WebDriverOrWebElement], Union[Literal[False], WebElement]]:
352355
"""An Expectation for checking an element is visible and enabled such that
353356
you can click it.
@@ -399,7 +402,7 @@ def _predicate(_):
399402
return _predicate
400403

401404

402-
def element_located_to_be_selected(locator: Tuple[str, str]) -> Callable[[WebDriverOrWebElement], bool]:
405+
def element_located_to_be_selected(locator: LocatorType) -> Callable[[WebDriverOrWebElement], bool]:
403406
"""An expectation for the element to be located is selected.
404407
405408
locator is a tuple of (by, path)
@@ -424,7 +427,7 @@ def _predicate(_):
424427

425428

426429
def element_located_selection_state_to_be(
427-
locator: Tuple[str, str], is_selected: bool
430+
locator: LocatorType, is_selected: bool
428431
) -> Callable[[WebDriverOrWebElement], bool]:
429432
"""An expectation to locate an element and check if the selection state
430433
specified is in that state.
@@ -474,7 +477,7 @@ def _predicate(driver: WebDriver):
474477
return _predicate
475478

476479

477-
def element_attribute_to_include(locator: Tuple[str, str], attribute_: str) -> Callable[[WebDriverOrWebElement], bool]:
480+
def element_attribute_to_include(locator: LocatorType, attribute_: str) -> Callable[[WebDriverOrWebElement], bool]:
478481
"""An expectation for checking if the given attribute is included in the
479482
specified element.
480483

0 commit comments

Comments
 (0)