Skip to content

Commit 3cf12d5

Browse files
committed
use selneium
1 parent 8f2b059 commit 3cf12d5

File tree

4 files changed

+153
-125
lines changed

4 files changed

+153
-125
lines changed

appium/webdriver/webdriver.py

Lines changed: 32 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@
6262
from .webelement import WebElement as MobileWebElement
6363

6464

65+
class AppiumLocatorConverter:
66+
def convert(self, by, value):
67+
return (by, value)
68+
69+
6570
class ExtensionBase:
6671
"""
6772
Used to define an extension command as driver's methods.
@@ -226,6 +231,8 @@ def __init__(
226231
super().__init__(
227232
command_executor=command_executor,
228233
options=options,
234+
locator_converter=AppiumLocatorConverter(),
235+
web_element_cls=MobileWebElement,
229236
)
230237

231238
if hasattr(self, 'command_executor'):
@@ -346,71 +353,38 @@ def get_status(self) -> Dict:
346353
"""
347354
return self.execute(Command.GET_STATUS)['value']
348355

349-
def find_element(self, by: str = AppiumBy.ID, value: Union[str, Dict, None] = None) -> MobileWebElement:
350-
"""
351-
Find an element given a AppiumBy strategy and locator
356+
# def find_element(self, by: str = AppiumBy.ID, value: Union[str, Dict, None] = None) -> MobileWebElement:
357+
# """
358+
# Find an element given a AppiumBy strategy and locator
352359

353-
Args:
354-
by: The strategy
355-
value: The locator
360+
# Args:
361+
# by: The strategy
362+
# value: The locator
356363

357-
Usage:
358-
driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value='accessibility_id')
364+
# Usage:
365+
# driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value='accessibility_id')
359366

360-
Returns:
361-
`appium.webdriver.webelement.WebElement`: The found element
367+
# Returns:
368+
# `appium.webdriver.webelement.WebElement`: The found element
362369

363-
"""
364-
# We prefer to patch locators in the client code
365-
# Checking current context every time a locator is accessed could significantly slow down tests
366-
# Check https://github.com/appium/python-client/pull/724 before submitting any issue
367-
# if by == By.ID:
368-
# by = By.CSS_SELECTOR
369-
# value = '[id="%s"]' % value
370-
# elif by == By.TAG_NAME:
371-
# by = By.CSS_SELECTOR
372-
# elif by == By.CLASS_NAME:
373-
# by = By.CSS_SELECTOR
374-
# value = ".%s" % value
375-
# elif by == By.NAME:
376-
# by = By.CSS_SELECTOR
377-
# value = '[name="%s"]' % value
378-
379-
return self.execute(RemoteCommand.FIND_ELEMENT, {'using': by, 'value': value})['value']
380-
381-
def find_elements(self, by: str = AppiumBy.ID, value: Union[str, Dict, None] = None) -> Union[List[MobileWebElement], List]:
382-
"""
383-
Find elements given a AppiumBy strategy and locator
370+
# """
371+
# return self.execute(RemoteCommand.FIND_ELEMENT, {'using': by, 'value': value})['value']
384372

385-
Args:
386-
by: The strategy
387-
value: The locator
373+
# def find_elements(self, by: str = AppiumBy.ID, value: Union[str, Dict, None] = None) -> Union[List[MobileWebElement], List]:
374+
# """
375+
# Find elements given a AppiumBy strategy and locator
388376

389-
Usage:
390-
driver.find_elements(by=AppiumBy.ACCESSIBILITY_ID, value='accessibility_id')
377+
# Args:
378+
# by: The strategy
379+
# value: The locator
391380

392-
Returns:
393-
:obj:`list` of :obj:`appium.webdriver.webelement.WebElement`: The found elements
394-
"""
395-
# We prefer to patch locators in the client code
396-
# Checking current context every time a locator is accessed could significantly slow down tests
397-
# Check https://github.com/appium/python-client/pull/724 before submitting any issue
398-
# if by == By.ID:
399-
# by = By.CSS_SELECTOR
400-
# value = '[id="%s"]' % value
401-
# elif by == By.TAG_NAME:
402-
# by = By.CSS_SELECTOR
403-
# elif by == By.CLASS_NAME:
404-
# by = By.CSS_SELECTOR
405-
# value = ".%s" % value
406-
# elif by == By.NAME:
407-
# by = By.CSS_SELECTOR
408-
# value = '[name="%s"]' % value
409-
410-
# Return empty list if driver returns null
411-
# See https://github.com/SeleniumHQ/selenium/issues/4555
412-
413-
return self.execute(RemoteCommand.FIND_ELEMENTS, {'using': by, 'value': value})['value'] or []
381+
# Usage:
382+
# driver.find_elements(by=AppiumBy.ACCESSIBILITY_ID, value='accessibility_id')
383+
384+
# Returns:
385+
# :obj:`list` of :obj:`appium.webdriver.webelement.WebElement`: The found elements
386+
# """
387+
# return self.execute(RemoteCommand.FIND_ELEMENTS, {'using': by, 'value': value})['value'] or []
414388

415389
def create_web_element(self, element_id: Union[int, str]) -> MobileWebElement:
416390
"""Creates a web element with the specified element_id.

appium/webdriver/webelement.py

Lines changed: 64 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,13 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from typing import Callable, Dict, List, Optional, Union
15+
from typing import Callable, Dict, Optional, Union
1616

1717
from selenium.webdriver.common.utils import keys_to_typing
1818
from selenium.webdriver.remote.command import Command as RemoteCommand
1919
from selenium.webdriver.remote.webelement import WebElement as SeleniumWebElement
2020
from typing_extensions import Self
2121

22-
from appium.webdriver.common.appiumby import AppiumBy
23-
2422
from .mobilecommand import MobileCommand as Command
2523

2624

@@ -80,69 +78,69 @@ def is_displayed(self) -> bool:
8078
"""
8179
return self._execute(Command.IS_ELEMENT_DISPLAYED)['value']
8280

83-
def find_element(self, by: str = AppiumBy.ID, value: Union[str, Dict, None] = None) -> 'WebElement':
84-
"""Find an element given a AppiumBy strategy and locator
85-
86-
Override for Appium
87-
88-
Prefer the find_element_by_* methods when possible.
89-
90-
Args:
91-
by: The strategy
92-
value: The locator
93-
94-
Usage:
95-
element = element.find_element(AppiumBy.ID, 'foo')
96-
97-
Returns:
98-
`appium.webdriver.webelement.WebElement`
99-
"""
100-
# We prefer to patch locators in the client code
101-
# Checking current context every time a locator is accessed could significantly slow down tests
102-
# Check https://github.com/appium/python-client/pull/724 before submitting any issue
103-
# if by == By.ID:
104-
# by = By.CSS_SELECTOR
105-
# value = '[id="%s"]' % value
106-
# elif by == By.TAG_NAME:
107-
# by = By.CSS_SELECTOR
108-
# elif by == By.CLASS_NAME:
109-
# by = By.CSS_SELECTOR
110-
# value = ".%s" % value
111-
# elif by == By.NAME:
112-
# by = By.CSS_SELECTOR
113-
# value = '[name="%s"]' % value
114-
115-
return self._execute(RemoteCommand.FIND_CHILD_ELEMENT, {'using': by, 'value': value})['value']
116-
117-
def find_elements(self, by: str = AppiumBy.ID, value: Union[str, Dict, None] = None) -> List['WebElement']:
118-
"""Find elements given a AppiumBy strategy and locator
119-
120-
Args:
121-
by: The strategy
122-
value: The locator
123-
124-
Usage:
125-
element = element.find_elements(AppiumBy.CLASS_NAME, 'foo')
126-
127-
Returns:
128-
:obj:`list` of :obj:`appium.webdriver.webelement.WebElement`
129-
"""
130-
# We prefer to patch locators in the client code
131-
# Checking current context every time a locator is accessed could significantly slow down tests
132-
# Check https://github.com/appium/python-client/pull/724 before submitting any issue
133-
# if by == By.ID:
134-
# by = By.CSS_SELECTOR
135-
# value = '[id="%s"]' % value
136-
# elif by == By.TAG_NAME:
137-
# by = By.CSS_SELECTOR
138-
# elif by == By.CLASS_NAME:
139-
# by = By.CSS_SELECTOR
140-
# value = ".%s" % value
141-
# elif by == By.NAME:
142-
# by = By.CSS_SELECTOR
143-
# value = '[name="%s"]' % value
144-
145-
return self._execute(RemoteCommand.FIND_CHILD_ELEMENTS, {'using': by, 'value': value})['value']
81+
# def find_element(self, by: str = AppiumBy.ID, value: Union[str, Dict, None] = None) -> 'WebElement':
82+
# """Find an element given a AppiumBy strategy and locator
83+
84+
# Override for Appium
85+
86+
# Prefer the find_element_by_* methods when possible.
87+
88+
# Args:
89+
# by: The strategy
90+
# value: The locator
91+
92+
# Usage:
93+
# element = element.find_element(AppiumBy.ID, 'foo')
94+
95+
# Returns:
96+
# `appium.webdriver.webelement.WebElement`
97+
# """
98+
# # We prefer to patch locators in the client code
99+
# # Checking current context every time a locator is accessed could significantly slow down tests
100+
# # Check https://github.com/appium/python-client/pull/724 before submitting any issue
101+
# # if by == By.ID:
102+
# # by = By.CSS_SELECTOR
103+
# # value = '[id="%s"]' % value
104+
# # elif by == By.TAG_NAME:
105+
# # by = By.CSS_SELECTOR
106+
# # elif by == By.CLASS_NAME:
107+
# # by = By.CSS_SELECTOR
108+
# # value = ".%s" % value
109+
# # elif by == By.NAME:
110+
# # by = By.CSS_SELECTOR
111+
# # value = '[name="%s"]' % value
112+
113+
# return self._execute(RemoteCommand.FIND_CHILD_ELEMENT, {'using': by, 'value': value})['value']
114+
115+
# def find_elements(self, by: str = AppiumBy.ID, value: Union[str, Dict, None] = None) -> List['WebElement']:
116+
# """Find elements given a AppiumBy strategy and locator
117+
118+
# Args:
119+
# by: The strategy
120+
# value: The locator
121+
122+
# Usage:
123+
# element = element.find_elements(AppiumBy.CLASS_NAME, 'foo')
124+
125+
# Returns:
126+
# :obj:`list` of :obj:`appium.webdriver.webelement.WebElement`
127+
# """
128+
# # We prefer to patch locators in the client code
129+
# # Checking current context every time a locator is accessed could significantly slow down tests
130+
# # Check https://github.com/appium/python-client/pull/724 before submitting any issue
131+
# # if by == By.ID:
132+
# # by = By.CSS_SELECTOR
133+
# # value = '[id="%s"]' % value
134+
# # elif by == By.TAG_NAME:
135+
# # by = By.CSS_SELECTOR
136+
# # elif by == By.CLASS_NAME:
137+
# # by = By.CSS_SELECTOR
138+
# # value = ".%s" % value
139+
# # elif by == By.NAME:
140+
# # by = By.CSS_SELECTOR
141+
# # value = '[name="%s"]' % value
142+
143+
# return self._execute(RemoteCommand.FIND_CHILD_ELEMENTS, {'using': by, 'value': value})['value']
146144

147145
def clear(self) -> Self:
148146
"""Clears text.

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,5 @@
4949
'Topic :: Software Development :: Quality Assurance',
5050
'Topic :: Software Development :: Testing',
5151
],
52-
install_requires=['selenium ~= 4.12'],
52+
install_requires=['selenium @ git+https://github.com/navin772/selenium.git@appium-python'],
5353
)

test/unit/webdriver/search_context/android_test.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,62 @@
2222

2323

2424
class TestWebDriverAndroidSearchContext(object):
25+
@httpretty.activate
26+
def test_find_element_by_id(self):
27+
driver = android_w3c_driver()
28+
httpretty.register_uri(
29+
httpretty.POST,
30+
appium_command('/session/1234567890/element'),
31+
body='{"value": {"element-6066-11e4-a52e-4f735466cecf": "element-id"}}',
32+
)
33+
el = driver.find_element(
34+
by=AppiumBy.ID,
35+
value='id data',
36+
)
37+
38+
d = get_httpretty_request_body(httpretty.last_request())
39+
assert d['using'] == 'id'
40+
assert d['value'] == 'id data'
41+
assert isinstance(el, MobileWebElement)
42+
43+
@httpretty.activate
44+
def test_find_elements_by_id(self):
45+
driver = android_w3c_driver()
46+
httpretty.register_uri(
47+
httpretty.POST,
48+
appium_command('/session/1234567890/elements'),
49+
body='{"value": [{"element-6066-11e4-a52e-4f735466cecf": "element-id1"}, '
50+
'{"element-6066-11e4-a52e-4f735466cecf": "element-id2"}]}',
51+
)
52+
els = driver.find_elements(
53+
by=AppiumBy.ID,
54+
value='id data',
55+
)
56+
57+
d = get_httpretty_request_body(httpretty.last_request())
58+
assert d['using'] == 'id'
59+
assert d['value'] == 'id data'
60+
assert isinstance(els[0], MobileWebElement)
61+
62+
@httpretty.activate
63+
def test_find_child_element_by_id(self):
64+
driver = android_w3c_driver()
65+
element = MobileWebElement(driver, 'element_id')
66+
httpretty.register_uri(
67+
httpretty.POST,
68+
appium_command('/session/1234567890/element/element_id/element'),
69+
body='{"value": {"element-6066-11e4-a52e-4f735466cecf": "child-element-id"}}',
70+
)
71+
el = element.find_element(
72+
by=AppiumBy.ID,
73+
value='id data',
74+
)
75+
76+
d = get_httpretty_request_body(httpretty.last_request())
77+
assert d['using'] == 'id'
78+
assert d['value'] == 'id data'
79+
assert isinstance(el, MobileWebElement)
80+
2581
@httpretty.activate
2682
def test_find_element_by_android_data_matcher(self):
2783
driver = android_w3c_driver()

0 commit comments

Comments
 (0)