Skip to content

Commit f5c2669

Browse files
committed
UiAutomatorHelper improvements and use of culebratester_client
- Create inner classes - Make some methods static - Mark methods deprecated - culebratester-client dependency 2.0.17 - Change venv
1 parent da64cbd commit f5c2669

File tree

5 files changed

+204
-19
lines changed

5 files changed

+204
-19
lines changed

.idea/AndroidViewClient.iml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@
2222
classifiers=['Development Status :: 4 - Beta',
2323
'Intended Audience :: Developers',
2424
'License :: OSI Approved :: Apache Software License'],
25-
install_requires=['setuptools', 'requests', 'numpy', 'matplotlib', 'culebratester-client >= 2.0.12'],
25+
install_requires=['setuptools', 'requests', 'numpy', 'matplotlib', 'culebratester-client >= 2.0.17'],
2626
)

src/androidviewclient.egg-info/requires.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ setuptools
22
requests
33
numpy
44
matplotlib
5-
culebratester-client
5+
culebratester-client>=2.0.17

src/com/dtmilano/android/uiautomator/uiautomatorhelper.py

Lines changed: 200 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
from __future__ import print_function
2222

23-
__version__ = '20.4.3'
23+
__version__ = '20.4.4'
2424

2525
import json
2626
import os
@@ -29,13 +29,14 @@
2929
import subprocess
3030
import sys
3131
import threading
32-
3332
import time
3433
from abc import ABC
3534

35+
import culebratester_client
36+
from culebratester_client import Text
37+
3638
from com.dtmilano.android.adb.adbclient import AdbClient
3739
from com.dtmilano.android.common import obtainAdbPath
38-
import culebratester_client
3940

4041
__author__ = 'diego'
4142

@@ -122,10 +123,11 @@ def __init__(self, adbclient, adb=None, localport=9987, remoteport=9987, hostnam
122123
print('⚠️ CulebraTester2 server should have been started and port redirected.', file=sys.stderr)
123124
# TODO: localport should be in ApiClient configuration
124125
self.api_instance = culebratester_client.DefaultApi(culebratester_client.ApiClient())
125-
self.device = UiAutomatorHelper.Device(self)
126-
self.target_context = UiAutomatorHelper.TargetContext(self)
127-
self.object_store = UiAutomatorHelper.ObjectStore(self)
128-
self.ui_device = UiAutomatorHelper.UiDevice(self)
126+
self.device: UiAutomatorHelper.Device = UiAutomatorHelper.Device(self)
127+
self.target_context: UiAutomatorHelper.TargetContext = UiAutomatorHelper.TargetContext(self)
128+
self.object_store: UiAutomatorHelper.ObjectStore = UiAutomatorHelper.ObjectStore(self)
129+
self.ui_device: UiAutomatorHelper.UiDevice = UiAutomatorHelper.UiDevice(self)
130+
self.ui_object2: UiAutomatorHelper.UiObject2 = UiAutomatorHelper.UiObject2(self)
129131

130132
def __connectSession(self):
131133
if DEBUG:
@@ -158,7 +160,8 @@ def __connectSession(self):
158160
# lock.release()
159161
return session
160162

161-
def __whichAdb(self, adb):
163+
@staticmethod
164+
def __whichAdb(adb):
162165
if adb:
163166
if not os.access(adb, os.X_OK):
164167
raise Exception('adb="%s" is not executable' % adb)
@@ -210,7 +213,8 @@ def __init__(self, uiAutomatorHelper) -> None:
210213
super().__init__()
211214
self.uiAutomatorHelper = uiAutomatorHelper
212215

213-
def intersection(self, l1, l2):
216+
@staticmethod
217+
def intersection(l1, l2):
214218
return list(set(l1) & set(l2))
215219

216220
def some(self, l1, l2):
@@ -240,7 +244,7 @@ def display_real_size(self):
240244

241245
def getDisplayRealSize(self):
242246
"""
243-
:deprecated: use uiAutomatorHelper.device.get_display_real_size()
247+
:deprecated: use uiAutomatorHelper.device.display_real_size()
244248
:return: the display real size
245249
"""
246250
return self.api_instance.device_display_real_size_get()
@@ -278,6 +282,14 @@ class ObjectStore(ApiBase):
278282
def __init__(self, uiAutomatorHelper) -> None:
279283
super().__init__(uiAutomatorHelper)
280284

285+
def clear(self):
286+
"""
287+
Clears all the objects.
288+
:see https://github.com/dtmilano/CulebraTester2-public/blob/master/openapi.yaml
289+
:return: the status
290+
"""
291+
return self.uiAutomatorHelper.api_instance.object_store_clear_get()
292+
281293
def list(self):
282294
"""
283295
List the objects.
@@ -286,6 +298,14 @@ def list(self):
286298
"""
287299
return self.uiAutomatorHelper.api_instance.object_store_list_get()
288300

301+
def remove(self, oid: int):
302+
"""
303+
Removes an object.
304+
:see https://github.com/dtmilano/CulebraTester2-public/blob/master/openapi.yaml
305+
:return: the status
306+
"""
307+
return self.uiAutomatorHelper.api_instance.object_store_remove_get(oid)
308+
289309
#
290310
# UiDevice
291311
#
@@ -398,7 +418,8 @@ def take_screenshot(self, scale=1.0, quality=90, **kwargs):
398418
:param kwargs:
399419
:return:
400420
"""
401-
return self.uiAutomatorHelper.api_instance.ui_device_screenshot_get(scale=scale, quality=quality, _preload_content=False, **kwargs)
421+
return self.uiAutomatorHelper.api_instance.ui_device_screenshot_get(scale=scale, quality=quality,
422+
_preload_content=False, **kwargs)
402423

403424
def wait_for_idle(self, **kwargs):
404425
"""
@@ -410,6 +431,74 @@ def wait_for_idle(self, **kwargs):
410431
"""
411432
return self.uiAutomatorHelper.api_instance.ui_device_wait_for_idle_get(**kwargs)
412433

434+
#
435+
# UiObject2
436+
#
437+
class UiObject2(ApiBase):
438+
"""
439+
Inner UiObject2 class.
440+
441+
Notice that this class does not require an OID in its constructor.
442+
"""
443+
444+
def __init__(self, uiAutomatorHelper) -> None:
445+
super().__init__(uiAutomatorHelper)
446+
447+
def clear(self, oid):
448+
"""
449+
Clears the text content if this object is an editable field.
450+
:see https://github.com/dtmilano/CulebraTester2-public/blob/master/openapi.yaml
451+
:param oid: the oid
452+
:return: the result of the operation
453+
"""
454+
return self.uiAutomatorHelper.api_instance.ui_object2_clear_get(oid=oid)
455+
456+
def click(self, oid):
457+
"""
458+
Clicks on this object.
459+
:see https://github.com/dtmilano/CulebraTester2-public/blob/master/openapi.yaml
460+
:param oid: the oid
461+
:return: the result of the operation
462+
"""
463+
return self.uiAutomatorHelper.api_instance.ui_object2_click_get(oid=oid)
464+
465+
def dump(self, oid):
466+
"""
467+
Dumps the content of an object.
468+
:see https://github.com/dtmilano/CulebraTester2-public/blob/master/openapi.yaml
469+
:param oid: the oid
470+
:return: the content
471+
"""
472+
return self.uiAutomatorHelper.api_instance.ui_object2_dump_get(oid=oid)
473+
474+
def get_text(self, oid):
475+
"""
476+
Returns the text value for this object.
477+
:see https://github.com/dtmilano/CulebraTester2-public/blob/master/openapi.yaml
478+
:param oid: the oid
479+
:return: the text
480+
"""
481+
return self.uiAutomatorHelper.api_instance.ui_object2_get_text_get(oid=oid)
482+
483+
def long_click(self, oid):
484+
"""
485+
Performs a long click on this object.
486+
:see https://github.com/dtmilano/CulebraTester2-public/blob/master/openapi.yaml
487+
:param oid: the oid
488+
:return: the result of the operation
489+
"""
490+
return self.uiAutomatorHelper.api_instance.ui_object2_long_click_get(oid=oid)
491+
492+
def set_text(self, oid, text):
493+
"""
494+
Sets the text content if this object is an editable field.
495+
:see https://github.com/dtmilano/CulebraTester2-public/blob/master/openapi.yaml
496+
:param oid: the oid
497+
:param text: the text
498+
:return: the result of the operation
499+
"""
500+
return self.uiAutomatorHelper.api_instance.ui_object2_set_text_post(oid=oid, body=Text(text))
501+
413502
def click(self, **kwargs):
414503
"""
415504
:deprecated:
@@ -494,10 +583,12 @@ def pressRecentApps(self):
494583
"""
495584
return self.__httpCommand('/UiDevice/pressRecentApps')
496585

497-
def swipe(self, startX=-1, startY=-1, endX=-1, endY=-1, steps=10, segments=[], segmentSteps=5):
586+
def swipe(self, startX=-1, startY=-1, endX=-1, endY=-1, steps=10, segments=None, segmentSteps=5):
498587
"""
499588
:deprecated:
500589
"""
590+
if segments is None:
591+
segments = []
501592
if startX != -1 and startY != -1:
502593
params = {'startX': startX, 'startY': startY, 'endX': endX, 'endY': endY, 'steps': steps}
503594
elif segments:
@@ -525,19 +616,36 @@ def waitForIdle(self, timeout):
525616
# UiObject2
526617
#
527618
def setText(self, oid, text):
619+
"""
620+
:deprecated:
621+
"""
528622
body = {'text': text}
529623
return self.api_instance.ui_object2_oid_set_text_post(body, oid)
530624

531625
def clickAndWait(self, uiObject2, eventCondition, timeout):
626+
"""
627+
628+
:deprecated:
629+
:param uiObject2:
630+
:param eventCondition:
631+
:param timeout:
632+
:return:
633+
"""
532634
params = {'eventCondition': eventCondition, 'timeout': timeout}
533635
return self.__httpCommand('/UiObject2/%d/clickAndWait' % uiObject2.oid, params)
534636

535637
def getText(self, oid):
536638
return self.api_instance.ui_object2_oid_get_text_get(oid)
537639

538640
def isChecked(self, uiObject=None):
641+
"""
642+
643+
:deprecated:
644+
:param uiObject:
645+
:return:
646+
"""
539647
# This path works for UiObject and UiObject2, so there's no need to handle both cases differently
540-
path = '/UiObject/%d/isChecked' % (uiObject.oid)
648+
path = '/UiObject/%d/isChecked' % uiObject.oid
541649
response = self.__httpCommand(path, None)
542650
r = json.loads(response)
543651
if r['status'] == 'OK':
@@ -571,6 +679,9 @@ def uiScrollable(self, path, params=None):
571679

572680

573681
class UiObject:
682+
"""
683+
A UiObject is a representation of a view.
684+
"""
574685
def __init__(self, uiAutomatorHelper, oid, response):
575686
self.uiAutomatorHelper = uiAutomatorHelper
576687
self.oid = oid
@@ -596,32 +707,106 @@ def setText(self, text):
596707

597708

598709
class UiObject2:
599-
def __init__(self, uiAutomatorHelper, oid):
710+
"""
711+
A UiObject2 represents a UI element. Unlike UiObject, it is bound to a particular view instance and can become
712+
stale.
713+
"""
714+
715+
def __init__(self, uiAutomatorHelper: UiAutomatorHelper, class_name: str, oid: int):
716+
"""
717+
Constructor.
718+
719+
:param uiAutomatorHelper: the uiAutomatorHelper instance.
720+
:param class_name: the class name of the UI object
721+
:param oid: the object id
722+
"""
600723
self.uiAutomatorHelper = uiAutomatorHelper
724+
self.class_name = class_name
601725
self.oid = oid
602726

727+
def clear(self):
728+
"""
729+
Clears the text content if this object is an editable field.
730+
:return: the result of the operation
731+
"""
732+
return self.uiAutomatorHelper.ui_object2.clear(oid=self.oid)
733+
603734
def click(self):
604-
self.uiAutomatorHelper.click(oid=self.oid)
735+
"""
736+
Clicks on this object.
737+
:return: the result of the operation
738+
"""
739+
return self.uiAutomatorHelper.ui_object2.click(oid=self.oid)
740+
741+
def dump(self):
742+
"""
743+
Dumps the content of the object/
744+
:return: the content of the object
745+
"""
746+
return self.uiAutomatorHelper.ui_object2.dump(oid=self.oid)
747+
748+
def get_text(self):
749+
"""
750+
Returns the text value for this object.
751+
:return: the text
752+
"""
753+
return self.uiAutomatorHelper.ui_object2.get_text(oid=self.oid)
754+
755+
def long_click(self):
756+
"""
757+
Performs a long click on this object.
758+
:return: the result of the operation
759+
"""
760+
return self.uiAutomatorHelper.ui_object2.long_click(oid=self.oid)
761+
762+
def set_text(self, text):
763+
"""
764+
Sets the text content if this object is an editable field.
765+
:param text: the text
766+
:return: the result of the operation
767+
"""
768+
return self.uiAutomatorHelper.ui_object2.set_text(oid=self.oid, text=text)
605769

606770
def clickAndWait(self, eventCondition, timeout):
771+
"""
772+
:deprecated:
773+
:param eventCondition:
774+
:param timeout:
775+
:return:
776+
"""
607777
self.uiAutomatorHelper.clickAndWait(uiObject2=self, eventCondition=eventCondition, timeout=timeout)
608778

609779
def isChecked(self):
610780
"""
611781
782+
:deprecated:
612783
:rtype: bool
613784
"""
614785
return self.uiAutomatorHelper.isChecked(uiObject=self)
615786

616787
def longClick(self):
788+
"""
789+
790+
:deprecated:
791+
"""
617792
self.uiAutomatorHelper.longClick(oid=self.oid)
618793

619794
def getText(self):
795+
"""
796+
797+
:deprecated:
798+
:return:
799+
"""
620800
# NOTICE: even if this is an uiObject2 we are invoking the only "getText" method in UiAutomatorHelper
621801
# passing the uiObject2 as uiObject
622802
return self.uiAutomatorHelper.getText(uiObject=self)
623803

624804
def setText(self, text):
805+
"""
806+
807+
:deprecated:
808+
:param text:
809+
"""
625810
# NOTICE: even if this is an uiObject2 we are invoking the only "setText" method in UiAutomatorHelper
626811
# passing the uiObject2 as uiObject
627812
self.uiAutomatorHelper.setText(uiObject=self, text=text)

0 commit comments

Comments
 (0)