class Mobile(): """ """ def __init__(self, android_serial = None): # logger.info("Importing Android library") # print "Importing Android library" # clm.message("Importing Android library") self.adb = ADB(android_serial) self.device = Device(android_serial) self.test_helper = TestHelper(android_serial) def set_serial(self, android_serial): """ Set device serial """ self.adb = ADB(android_serial) self.device = Device(android_serial) self.test_helper = TestHelper(android_serial) def get_info(self): """ Retrieve the device info """ return self.device.info #Key Event Actions of the device """ Turn on/off screen """ def turn_on_screen(self): """ Turn on screen """ self.device.screen.on() def turn_off_screen(self): """ Turn off screen """ self.device.screen.off() def wakeup_the_device(self): """ wakeup the device """ self.device.wakeup() """ Press hard/soft key """ def press_key(self, *key): """ press *key* keycode """ self.device.press(*key) def press_home(self): """ press home key """ self.device.press.home() def press_back(self): """ press back key """ self.device.press.back() def press_left(self): """ press left key """ self.device.pres.left() def press_right(self): """ press right key """ self.device.press.right() def press_up(self): """ press up key """ self.device.press.up() def press_down(self): """ press down key """ self.device.press.down() def press_center(self): """ press center key """ self.device.press.center() def press_menu(self): """ press menu key """ self.device.press.menu() def press_search(self): """ press search key """ self.device.press.search() def press_enter(self): """ press enter key """ self.device.press.enter() def press_delete(self): """ press delete key """ self.device.press.delete() def press_recent(self): """ press recent key """ self.device.press.recent() def press_volume_up(self): """ press volume up key """ self.device.press.volume_up() def press_volume_down(self): """ press volume down key """ self.device.press.volume_down() def press_camera(self): """ press camera key """ self.device.press.camera() def press_power(self): """ press power key """ self.device.press.power() #Gesture interaction of the device def click(self, x, y): """ click (x, y) on screen """ self.device.click(x, y) def swipe(self, sx, sy, ex, ey, steps=10): """ swipe from (sx, sy) to (ex, ey) with steps """ self.device.swipe(sx, sy, ex, ey, steps) # Swipe from the center of the ui object to its edge def swipe_left(self, obj, steps=10): """ swipe the *obj* from center to left """ obj.swipe.left(steps=steps) def swipe_right(self, obj, steps=10): """ swipe the *obj* from center to right """ obj.swipe.right(steps=steps) def swipe_top(self, obj, steps=10): """ swipe the *obj* from center to top """ obj.swipe.top(steps=steps) def swipe_bottom(self, obj, steps=10): """ swipe the *obj* from center to bottom """ obj.swipe.bottom(steps=steps) def drag(self,sx, sy, ex, ey, steps=10): """ drag from (sx, sy) to (ex, ey) with steps """ self.device.drag(sx, sy, ex, ey, steps) #Wait until the specific ui object appears or gone # wait until the ui object appears def wait_for_exists(self, timeout=0, *args, **attribute): """ true means the object which has *attribute* exist false means the object does not exist in the given timeout """ return self.device(**attribute).wait.exists(timeout=timeout) # wait until the ui object gone def wait_until_gone(self, timeout=0, *args, **attribute): """ true means the object which has *attribute* disappear false means the object exist in the given timeout """ return self.device(**attribute).wait.gone(timeout=timeout) def wait_for_object_exists(self, obj, timeout=0): """ true means the object exist false means the object does not exist in the given timeout """ return obj.wait.exists(timeout=timeout) # wait until the ui object gone def wait_until_object_gone(self, obj, timeout=0): """ true means the object disappear false means the object exist in the given timeout """ return obj.wait.gone(timeout=timeout) # Perform fling on the specific ui object(scrollable) def fling_forward_horizontally(self, obj): """ return whether the object can be fling or not """ return obj.fling.horiz.forward() def fling_backward_horizontally(self, obj): """ return whether the object can be fling or not """ return obj.fling.horiz.backward() def fling_forward_vertically(self, obj): """ return whether the object can be fling or not """ return obj.fling.vert.forward() def fling_backward_vertically(self, obj): """ return whether the object can be fling or not """ return obj.fling.vert.backward() # Perform scroll on the specific ui object(scrollable) def scroll_to_beginning_vertically(self, obj, steps=10): """ """ return obj.scroll.vert.toBeginning(steps=steps) def scroll_forward_horizontally(self, obj, steps=10): """ return whether the object can be fling or not """ return obj.scroll.horiz.forward(steps=steps) def scroll_backward_horizontally(self, obj, steps=10): """ return whether the object can be fling or not """ return obj.scroll.horiz.backward(steps=steps) def scroll_to_horizontally(self, obj, *args,**attribute): """ return whether the object can be fling or not """ return obj.scroll.horiz.to(**attribute) def scroll_forward_vertically(self, obj, steps=10): """ return whether the object can be fling or not """ return obj.scroll.vert.forward(steps=steps) def scroll_backward_vertically(self, obj, steps=10): """ return whether the object can be fling or not """ return obj.scroll.vert.backward(steps=steps) def scroll_to_vertically(self, obj, *args, **attribute): """ return whether the object can be fling or not """ msg = '' for key, value in attribute.iteritems(): msg += ' %s=%s ' % (key, value) print msg # print 'args:' + args[0] return obj.scroll.vert.to(**attribute) #Screen Actions of the device def screenshot(self, scale=None, quality=None): """ Take a screenshot of device and log in the report with timestamp """ output_dir = BuiltIn().get_variable_value('${OUTPUTDIR}') ts = time.time() st = datetime.datetime.fromtimestamp(ts).strftime('%Y%m%d%H%M%S') screenshot_path = '%s%s%s.png' % (output_dir, os.sep, st) self.device.screenshot(screenshot_path, scale, quality) logger.info('\n<a href="%s">%s</a><br><img src="%s">' % (screenshot_path, st, screenshot_path), html=True) #Watcher # def register_click_watcher(self, watcher_name, attributes, *condition_list): # """ # The watcher click on the object which has the attributes when conditions match # """ # print type(attributes) # watcher = self.device.watcher(watcher_name) # for condition in condition_list: # watcher.when(**condition) # watcher.click(**attributes) # self.device.watchers.run() # print 'register watcher:%s' % watcher_name # return def __unicode_to_dict(self, a_unicode): a_dict = dict() dict_item_count = a_unicode.count('=') for count in range(dict_item_count): equal_sign_position = a_unicode.find('=') comma_position = a_unicode.find(',') a_key = a_unicode[0:equal_sign_position] if comma_position == -1: a_value = a_unicode[equal_sign_position + 1:] else: a_value = a_unicode[equal_sign_position + 1:comma_position] a_unicode = a_unicode[comma_position + 1:] a_dict[a_key] = a_value return a_dict def register_click_watcher(self, watcher_name, attributes, *condition_list): """ The watcher click on the object which has the *attributes* when conditions match """ watcher = self.device.watcher(watcher_name) for condition in condition_list: watcher.when(**self.__unicode_to_dict(condition)) watcher.click(**self.__unicode_to_dict(attributes)) self.device.watchers.run() def register_press_watcher(self, watcher_name, press_keys, *condition_list): """ The watcher perform *press_keys* action sequentially when conditions match """ def unicode_to_list(a_unicode): a_list = list() comma_count = a_unicode.count(',') for count in range(comma_count + 1): comma_position = a_unicode.find(',') if comma_position == -1: a_list.append(str(a_unicode)) else: a_list.append(a_unicode[0:comma_position]) a_unicode = a_unicode[comma_position + 1:] return a_list watcher = self.device.watcher(watcher_name) for condition in condition_list: watcher.when(**self.__unicode_to_dict(condition)) watcher.press(*unicode_to_list(press_keys)) self.device.watchers.run() def remove_watchers(self, watcher_name = None): """ remove watcher with *watcher_name* or remove all watchers """ if watcher_name == None: self.device.watchers.remove() else: self.device.watchers.remove(watcher_name) def list_all_watchers(self): """ return the watcher list """ return self.device.watchers #Selector def get_object(self, *args, **attribute): """ get the ui object with attribute *attribute* """ msg = '' for key, value in attribute.iteritems(): msg += ' %s=%s ' % (key, value) print msg return self.device(*args, **attribute) def get_info_of_object(self, obj): """ return info dictionary of the *obj* The info example: { u'contentDescription': u'', u'checked': False, u'scrollable': True, u'text': u'', u'packageName': u'com.android.launcher', u'selected': False, u'enabled': True, u'bounds': { u'top': 231, u'left': 0, u'right': 1080, u'bottom': 1776 }, u'className': u'android.view.View', u'focusable': False, u'focused': False, u'clickable': False, u'checkable': False, u'chileCount': 1, u'longClickable': False, u'visibleBounds': { u'top': 231, u'left': 0, u'right': 1080, u'bottom': 1776 } } """ return obj.info def click_on(self, *args, **attribute): """ click on the object with *attribute* """ self.device(**attribute).click() def long_click_on(self, *args, **attribute): """ click on the object with *attribute* """ self.device(**attribute).long_click() def call(self, obj, method, *args, **attribute): func = getattr(obj, method) return func(**attribute) def set_text(self, text, *args, **attribute): """ set *text* to the Component which has the *attribute* """ self.device(**attribute).set_text(text) def clear_text(self, *args, **attributes): """ Clear text of the component with *attributes* """ while True: target = self.device(**attributes) text = target.info['text'] target.clear_text() remain_text = target.info['text'] if text == '' or remain_text == text: break # Other feature def sleep(self, time): """ sleep(no action) for *time* (in millisecond) """ target = 'wait for %s' % str(time) self.device(text=target).wait.exists(timeout=time) def install(self, apk_path): self.adb.cmd('install "%s"' % apk_path) def uninstall(self, package_name): self.adb.cmd('uninstall %s' % package_name) def type(self, text): """ Type *text* at current focused component """ self.test_helper.send_set_text_cmd(text) def foo(self): pass # logger.info('\nGot arg %s %s' % (output_dir, st), also_console=True) # clm = CommandLineWriter() # output some messages on console # clm.message(' ') # clm.message(u'中文') # clm.message(u'2----------2') def test(self): pass
def callUiautomator(opt, serial): d = Device(serial) d.wakeup() time.sleep(2) # home d.press.home() time.sleep(2) # Menu_click if (d(text='Phone', className='android.widget.TextView').exists): d(text='Phone', className='android.widget.TextView').click() time.sleep(2) d(text='Dial', className='android.widget.TextView').click() time.sleep(2) d(resourceId="com.android.contacts:id/digits").clear_text() for i in opt: if (i == "+"): d(text='0', className='android.widget.TextView').long_click() else: d(text=i, className='android.widget.TextView').click() time.sleep(2) d(className='android.widget.ImageButton', resourceId='com.android.contacts:id/btnLogsCall').click() time.sleep(1) return True else: print("Phone is not at home") return False
def unlock_screen(self): print "[INFO]: Unlock screen" d = Device(self.serial) for i in range(10): d.wakeup() time.sleep(1.5) name = "com.android.systemui:id/lock_icon" if d(resourceId=name).exists: d(resourceId=name).drag.to( resourceId="com.android.systemui:id/clock_view", steps=100) if d(resourceId=name).exists == False: break assert d(resourceId=name).exists == False
def postMes(): ''' 入参: device:设备ID path:绝对路径,该路径下存放文案和图片,其中文案存放在txt文件中 例: /postmes?device=fa16c0f&path=D:\\xiaohongshu ''' deviceId = request.args.get('device', '') path = request.args.get('path', '') d = Device(deviceId) fileList = [] title = '' context = '' for file in os.listdir(path): filePath = os.path.join(path, file) if os.path.splitext(filePath)[1] == '.txt': with open(filePath, encoding='utf8') as f: allLines = f.readlines() title = allLines[0] context = ''.join(allLines[1:]) continue if not os.path.isdir(filePath): pushFile(deviceId, file, filePath) fileList.append(file) d.wakeup() openApp(d, deviceId) waitAndClick(d, 'com.xingin.xhs:id/bo5') d(resourceId='com.xingin.xhs:id/bq8').wait.exists(timeout=10000) for i in range(len(fileList)): d(resourceId='com.xingin.xhs:id/bmu')[i].click() waitAndClickText(d, '下一步(%s)' % (len(fileList))) # waitAndClick(d, 'com.xingin.xhs:id/wg') waitAndClick(d, 'com.xingin.xhs:id/aeu') d(text='发布笔记').wait.exists(timeout=10000) if title: d(resourceId='com.xingin.xhs:id/atm').set_text(title) if context: d(resourceId='com.xingin.xhs:id/ase').set_text(context) waitAndClickText(d, '发布笔记') # waitAndClick(d, 'com.xingin.xhs:id/bnb') if d(resourceId='com.xingin.xhs:id/drw').info['selected']: d(resourceId='com.xingin.xhs:id/drw').click() waitAndClick(d, 'com.xingin.xhs:id/bp9') # waitAndClick(d, 'com.xingin.xhs:id/a2i') waitAndClickText(d, '发布笔记') d(text='保存到相册').wait.exists(timeout=10000) os.system('adb -s %s shell am force-stop com.xingin.xhs' % (deviceId)) delFiles(deviceId, fileList) return {'status': 1}
def tw_up_dev(device, doc): ''' cmd = "adb -s {} install Twitter.apk".format(device) result = os.popen(cmd).read() if "Success" in result: pass else: return 500 ''' cmd = 'adb -s {} shell "su -c" am start -n com.twitter.android/.DispatchActivity'.format( device) result = os.popen(cmd).read() if "Starting: Intent { cmp=com.twitter.android/.DispatchActivity }" in result: d = Device(device) if d.screen == "off": d.wakeup() d.watcher("fbui_tooltip").when( resourceId="com.yulong.android.seccenter:id/alertdlg_forbid" ).click(resourceId="com.yulong.android.seccenter:id/alertdlg_forbid") d.watchers.run() x = tw_register(d, device, doc) return x else: return 501
from uiautomator import Device import utility.common as u def enable_developer_setting(self, name): checkbox = self(className="android.widget.ListView",resourceId="android:id/list").\ child_by_text(name,className="android.widget.LinearLayout").\ child(className="android.widget.CheckBox") if checkbox.checked == False: print (name + " is not enabled, enabling it") checkbox.click() else: print(name + " enabled") def ChangeDeveloper_settings(self): package = 'com.android.settings' activity = '.DevelopmentSettings' component_name = package + '/' + activity u.start_activity(self,component_name) self.wait.update() enable_developer_setting(self,u'Stay awake') enable_developer_setting(self,u'Allow mock locations') if __name__ == '__main__': d = Device() d.wakeup() # Press the HOME button to start the test from the home screen d.press.home() ChangeDeveloper_settings(d) # Press the HOME button to start the test from the home screen # d.press.home()
class FnatDevice(Device): def __init__(self, serial_no): Device.__init__(self, serial_no) self.serial = serial_no if 0 != cmp(self.serial.upper(), "FAKE"): self.d = Device(self.serial) def wakeup(self): if 0 != cmp(self.serial.upper(), "FAKE"): self.d.wakeup() else: pass def launch_from_home(self, list_of_icons): self.d.press.home() app_icon = self.d(packageName="com.android.launcher", description="Apps") if 0 <= self.wait_for_object_v(app_icon, 3): app_icon.click() widget_tab = self.d(packageName="com.android.launcher", description="Widgets") if 0 > self.wait_for_object_v(widget_tab, 3): return False size_list = len(list_of_icons) center_point = (-1, -1) for i in range(0, size_list - 1): self.screenshot("pata_fullscreen.png") center_point = find_obj( config["__log_dir"] + "/pata_fullscreen.png", config["__testset_root"] + "/icons/" + list_of_icons[i]) if center_point[0] < 0 or center_point[1] < 0: return False else: self.d.click(center_point[0], center_point[1]) return True else: return False def wait_for_object_v(self, obj_selector, timeout, by_force=False): while (timeout >= 0): if obj_selector.exists: return timeout timeout = timeout - 1 time.sleep(1) if True == by_force: assert False else: return -1 def wait_for_object_x(self, obj_selector, timeout, by_force=False): while (timeout >= 0): if not obj_selector.exists: return timeout timeout = timeout - 1 time.sleep(1) if True == by_force: assert False else: return -1 def wait_for_object_description(self, obj_selector, expected_value, timeout, by_force=False): while (timeout >= 0): if obj_selector.exists: obj_description = obj_selector.description if str(obj_description) == expected_value: return timeout timeout = timeout - 1 time.sleep(1) if True == by_force: assert False else: return -1 def unlock(self): if 0 != cmp(self.serial.upper(), "FAKE"): icon_lock = self.d(resourceId="com.android.systemui:id/lock_icon") if icon_lock.exists: icon_lock.drag.to(icon_lock.bounds["left"], 0) self.wait_for_object_x(icon_lock, 5, True) else: pass def screenshot(self, png_file): this_cmd = "adb -s " + self.serial + " shell /system/bin/screencap -p | sed 's/\r$//' > " + config[ "__log_dir"] + "/" + png_file os.system(this_cmd) def run_adb_cmd(self, adb_cmd): this_cmd = "adb -s " + self.serial + " shell " + adb_cmd return os.popen(this_cmd).readlines()
#! /Users/kingname/Project/scrapy_venv/bin/python from uiautomator import Device device = Device() device.wakeup() wechat_icon = device(text='微信') if not wechat_icon.exists: device.swipe(400, 600, 0, 600) if wechat_icon.exists: wechat_icon.click() device(scrollable=True).scroll.vert.toBeginning() while True: girl_friend = device(text='女朋友') if girl_friend.exists: girl_friend.click() break else: device(scrollable=True).scroll.vert.forward() device(className="android.widget.EditText").set_text('早上好,本消息为自动发送。') device.press.back() send_button = device(text="发送") if send_button.exists: send_button.click()
class UiTestLib(object): """Ui Test Lib """ def __init__(self, serial=None): """ """ logger.info('<p>Device=%s>' % serial, html=True) print '<p>Device=%s>' % serial self._result = '' self.starttime = 0 self.d = Device(serial) self.adb = Adb(serial) self.debug = 'True' def set_debugable(flag): self.debug = flag def set_serial(self, serial): """Specify given *serial* device to perform test. or export ANDROID_SERIAL=CXFS42343 if you have many devices connected but you don't use this interface When you need to use multiple devices, do not use this keyword to switch between devices in test execution. And set the serial to each library. Using different library name when importing this library according to http://robotframework.googlecode.com/hg/doc/userguide/RobotFrameworkUserGuide.html?r=2.8.5. Examples: | Setting | Value | Value | Value | | Library | UiTestLib | WITH NAME | Mobile1 | | Library | UiTestLib | WITH NAME | Mobile2 | And set the serial to each library. | Test Case | Action | Argument | | Multiple Devices | Mobile1.Set Serial | device_1's serial | | | Mobile2.Set Serial | device_2's serial | """ self.d = Device(serial) self.adb = Adb(serial) def logmsg(self, msg): if self.debug == 'True': print msg def exe_adb_command(self, cmd): """ Execute adb *cmd* Examples: | Exe Adb Command | shell getprop | """ return self.adb.cmd(cmd).wait() def exe_adb_and_result(self, cmd): """Execute adb *cmd* and return lines of the command""" lproc = self.adb.cmd(cmd) lproc.poll() lines = lproc.stdout.readlines() return lines def get_device_info(self): """Get Device information return info dictionary """ return self.d.info def light_screen(self): """Light screen by wakeup. Examples: | Action | |Light screen| Use `Light screen` to light screen. """ self.d.wakeup() self._result = self.d.press.home() def open_application(self, appname): """Open application by it name `appname`. Example: | Action | Argument | | Open application | "com.android.settings/com.android.settings.Settings" | """ appname = 'shell am start -n ' + appname print 'Open Application:', appname self._result = self.exe_adb_command(appname) def click_text(self, text, instance=0): """Click text label on screen instance=0 is default, change when you needed. Example: | Action | Argument | Argument | | Click Text | text | instance | """ return self.d(text=text, instance=instance).click.wait() def long_click_text(self, text, instance=0): """ Long Click text label on screen, *text* and *instance=0* Example: | Action | Argument | Argument | | Long Click Text | text | instance | """ return self.d(text=text, instance=instance).long_click() def long_click_ui(self, **selectors): """ Long Click on **selectors** Selector supports below parameters. Refer to UiSelector java doc for detailed information. text, textContains, textMatches, textStartsWith className, classNameMatches description, descriptionContains, descriptionMatches, descriptionStartsWith checkable, checked, clickable, longClickable scrollable, enabled,focusable, focused, selected packageName, packageNameMatches resourceId, resourceIdMatches index, instance Example: | Action | Argument | Argument | Argument | | Long Click UI | text=XXXX | className=XXX.xxxx | resourceId=xxxxxx | """ return self.d(**selectors).long_click() def text_display_on_screen_contains(self, text): """Verify text display on screen Example: | Action | Argument | |Text display on screen is| text | """ if self.d(text=text).exists: self._result = True return True else: self._result = False return False def object_display_on_screen(self, obj, timeout=5000): """ Verify *obj* UiObject display on screen return to self._result Example: | Action | Argument | |Object display on screen | obj | """ if obj.wait.exists(timeout): self._result = True return True else: self._result = False return False def assert_expectation(self, expect, actual): """ Assert Expectation and actual value Example: | Action | args | args | | Assert Expectation | 324324 | ${actual} | """ if str(expect) != str(actual): raise AssertionError( 'Actual result is = %s, but expectation is: %s' % (str(actual), str(expect))) def assert_true(self, condition): """ Assert True of *condition Example: |Assert True | condition | """ if str(condition) != 'True': #because only string from robotframework raise AssertionError('Result is = %s' % str(condition)) def assert_result_true(self): """ Assert True of *self._result Example: |Assert True | """ if self._result != True: raise AssertionError('Result is = %s' % str(self._result)) def wait_for_ui_exists(self, timeout, **selectors): """ Return True if Selector is to identify specific ui object in current window. # To seleted the object ,text is 'Clock' and its className is 'android.widget.TextView' wait_for_ui_exists(text='Clock', className='android.widget.TextView') Selector supports below parameters. Refer to UiSelector java doc for detailed information. text, textContains, textMatches, textStartsWith className, classNameMatches description, descriptionContains, descriptionMatches, descriptionStartsWith checkable, checked, clickable, longClickable scrollable, enabled,focusable, focused, selected packageName, packageNameMatches resourceId, resourceIdMatches index, instance Examples: | Action | Argument | Argument | Argument | Argument | |Wait For UI Exists | timeout | text=XXXX | className=XXX.xxxx | resourceId=xxxxxx | """ self._result = self.d(**selectors).wait.exists(timeout=int(timeout)) return self._result def wait_and_click(self, timeout, **selectors): """Wait for uiselector and click""" if self.d(**selectors).wait.exists(timeout=int(timeout)): self.d(**selectors).click() def assert_ui_exists(self, **selectors): """ Assert UiObject appear on the screen Examples: | Action | Argument | Argument | Argument | Argument | |Assert UI Exists | timeout | text=XXXX | className=XXX.xxxx | resourceId=xxxxxx | """ if not self.d(**selectors).wait.exists(): raise AssertionError('UiObject does not exists %s' % selectors.items()) def result_should_be(self, expected): """Verifies that the current result is `expected`. Example: | Action | Argument | | Open application | com.android.settings/com.android.settings.Settings | | Result Should Be | 0 | """ print('result is: %s\n', self._result) print('ex is: %s\n', expected) if str(self._result) != expected: raise AssertionError('%s != %s' % (self._result, expected)) def click_at_coordinates(self, x, y): """ Click at (x,y) coordinates. Example: | Action | Argument | Argument | | Click At Corrdinates | x | y | """ return self.d.click(int(x), int(y)) def long_click_at_coordinates(self, x, y): """ # long click (x, y) on screen """ return self.d.long_click(int(x), int(y)) def swipe(self, sx, sy, ex, ey, steps=20): """ Swipe from (sx,sy) to (ex,ey) """ return self.d.swipe(int(sx), int(sy), int(ex), int(ex), int(steps)) def drag(self, sx, sy, ex, ey, steps=20): """ Drag from (sx,sy) to (ex,ey) """ return self.d.drag(int(sx), int(sy), int(ex), int(ex), int(steps)) def freeze_rotation(self, rotation=True): """ Freeze rotation, *rotation*, True is default, """ return self.d.freeze_rotation(rotation) def set_rotation(self, rotation): """ # retrieve orientation, # it should be "natural" or "left" or "right" or "upsidedown" Example: | Action | Argument | | Set Rotation | nature | | Set Rotation | left | | Set Rotation | right | | Set Rotation | upsidedown | """ orientation = self.d.orientation if rotation == "nature": self.d.orientation = "n" # or "natural" elif rotation == "left": self.d.orientation = "l" # or "left" elif rotation == "right": self.d.orientation = "r" # or "right" elif rotation == "upsidedown": self.d.orientation = "upsidedown" # or "upsidedown" else: self.d.rotation = "n" def take_screenshot(self, scale=None, quality=None): """ Take a screenshot of device and log in the report with timestamp, scale for screenshot size and quality for screenshot quality default scale=1.0 quality=100 Example: | Action | Argument | Argument | | Take Screenshot | 0.5 | 80 | """ output_dir = BuiltIn().get_variable_value('${OUTPUTDIR}') ts = time.time() st = datetime.datetime.fromtimestamp(ts).strftime('%Y%m%d%H%M%S') screenshot_path = '%s%s%s.png' % (output_dir, os.sep, st) screenshot_name = '%s%s.png' % (os.sep, st) self.d.screenshot(screenshot_path, scale, quality) logger.info('\n<a href="%s">%s</a><br><img src="%s">' % (screenshot_path, st, screenshot_name), html=True) def open_notification(self): """ Open notification of the phone """ self.d.open.notification() def wait_window_update(self): """ wait for window update """ return self.d.wait.update() def wait_window_idle(self): """ wait for window idle """ return self.d.wait.idle() def remove_watchers(self): """ Remove UI watchers """ self.d.watchers.remove() def get_device(self): """ Get device object, you can do any command using this """ return self.d def click_id(self, id, instance=0): """ Click *id* with *instance*=0 """ return self.d(resourceId=id, instance=instance).click.wait() def long_click_id(self, id, instance=0): """ Long click *id* with *instance*=0 """ return self.d(resourceId=id, instance=0).long_click() def click_description(self, description, instance=0): """ Click *description* with *instance*=0 """ return self.d(description=description, instance=instance).long_click() def click_class(self, className, instance=0): """ Click *className* with *instance*=0 """ return self.d(className=className, instance=instance).long_click() def type_text(self, textStr, **selectors): """ type text on selectors like text=EditName """ self.d(**selectors).set_text(textStr) def press_key(self, key): """ Press Key of following value home back left right up down center menu search enter delete(or del) recent(recent apps) volume_up volume_down volume_mute camera power Examples: | Action | Argument | | Press Key | home | | Press Key | back | | Press Key | left | | Press Key | right | | Press Key | recent | | Press Key | volume_up | | Press Key | camera | """ if key.isdigit(): return self.d.press(int(key)) return self.d.press(key) def phone_sleep(self, timeout): """ android device sleep with timeout in ms, don't use for executor sleep, """ return self.d.wait(int(timeout)) def execute_command(self, cmd, block_parent_process=True): """ Execute shell *cmd* command, with block_parent_process = True If block_parent_process = False, kill_command is needed to terminal the child process Example: | Execute Command | ping -c 5 127.0.0.1 | """ if str(block_parent_process) == str(True): return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() else: return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) def kill_command(self, process, timeout=0): """ Kill child *process* in timeout seconds Some bugs after process teminated """ time.sleep(float(timeout)) process.terminate() def wait_for_logcat(self, log, timeout=30): """ Wait log exists in given timeout, return True if have, otherwise will return False log is your want to search, log can be a regular expression time in seconds, default value is 30 seconds Example: | Wait For Logcat | .*ActivityManager.*cmp=com.sonyericsson.album/com.sonyericsson.album.Main.* | """ start = time.time() while (time.time() - start) < int(timeout): log_proc = self.adb.cmd("logcat -d -v time") returncode = log_proc.poll() lines = log_proc.stdout.readlines() for line in lines: rlt = re.search(log, line.rstrip()) if rlt is not None: print rlt.group(0) self._result = True return True time.sleep(2) #sleep 2s to wait self._result = False return False def clear_logcat(self): """ Clear logcat, it's often used before you want to use *wait_for_logcat()* """ print "Clear logcat before test" return self.exe_adb_command("logcat -c") def click_object(self, obj): """ Click UiObject *obj* Exmaple: | ${result} | Get UI Object | text=XXX | className=xxxx | | Click Object | ${result} | """ obj.click() def click_ui(self, **selectors): """ Click selector click_selector(text="Home", resourceId = "android:id/title") for **selector, please refer *get_ui_object()* Selector supports below parameters. Refer to UiSelector java doc for detailed information. text, textContains, textMatches, textStartsWith className, classNameMatches description, descriptionContains, descriptionMatches, descriptionStartsWith checkable, checked, clickable, longClickable scrollable, enabled,focusable, focused, selected packageName, packageNameMatches resourceId, resourceIdMatches index, instance Operation for a UiObjects: click, clear_text, drag(obj).to(**selector), gesture, exists, set_text, long_click pinch.In(percent=100, steps=10), pinch.Out(percent=100, steps=100),.swipe.right(), .swipe.left(steps=10),.swipe("right", steps=20),.wait.gone(),.wait.exists() """ print "selectors:", selectors return self.d(**selectors).click() def get_ui_object(self, **selectors): """ Get UI object with *selectors* you can do anything on UiObject, like click(), long_click(),wait.exists(timeout) examples: get_ui_object(text="Home", resourceId = "android:id/title") Selector supports below parameters. Refer to UiSelector java doc for detailed information. text, textContains, textMatches, textStartsWith className, classNameMatches description, descriptionContains, descriptionMatches, descriptionStartsWith checkable, checked, clickable, longClickable scrollable, enabled,focusable, focused, selected packageName, packageNameMatches resourceId, resourceIdMatches index, instance Operation for a UiObjects: click, clear_text, drag(obj).to(**selector), gesture, exists, set_text, long_click pinch.In(percent=100, steps=10), pinch.Out(percent=100, steps=100),.swipe.right(), .swipe.left(steps=10),.swipe("right", steps=20),.wait.gone(),.wait.exists() Exmaple: | ${result} | Get UI Object | text=XXX | className=xxxx | """ self._result = self.d(**selectors) return self._result def wait_for_object_exists(self, obj, timeout=0): """ Wait for UiObject *obj* exists in *timeout*= 0 Example: | ${result} | Get UI Object | text=XXX | className=xxxx | | Wait For Object Exists | ${result} | timeout | """ self._result = obj.wait.exists(timeout=int(timeout)) return self._result def wait_for_ui_gone(self, timeout=0, **selectors): """ Wait for UiObject *obj* gone in *timeout*= 0 Example: | ${result} | Get UI Object | text=XXX | className=xxxx | | Wait For Object Gone | ${result} | timeout | """ self._result = self.d(**selectors).wait.gone(timeout=int(timeout)) return self._result def get_key_value(self, key, dictionary): """ Get key value of dictionary """ return dictionary(key) def get_tts(self, input_text, delete_file=False, **args): """ Get TTS voice mp3 from Google get_tts(input_text='tunnel snakes rule apparently', args = {'language':'en','output':'outputto.mp3'}) Robot Framework: Examples: | Action | Argument | Argument | Argument | Argument | | UiTestLib.Get TTS | Hello world | False | output=ooo.mp3 | language=en | """ print "Get text to speech: ", input_text downloaded = False if str(delete_file) == 'True': if os.path.exists(args['output']): os.remove(args['output']) if os.path.exists(args['output']): if os.path.getsize(args['output']) <= 0: os.remove(args['output']) if args['output'] is not None: if not os.path.exists(args['output']): print 'Generating mp3 file......', args['output'] downloaded = GoogleTTS.audio_extract(input_text, args) else: print 'Have same local file' downloaded = True if not downloaded: print "Downloaded TTS from Google failed, trying to download from local FTP..." mp3file = open(args['output'], 'w') mp3url = 'ftp://cnbjlx9548/atautomation/Test-Content/Croft/' + args[ 'output'] try: resp = urllib2.urlopen(mp3url, timeout=40) mp3file.write(resp.read()) time.sleep(.05) except Exception, e: print e return False mp3file.close() return True
""" Keeps Android from falling asleep (warm!) by tapping every five seconds Usage: python warm.py [adb device id] """ import sys import os import time from uiautomator import Device DEVICE_NAME = sys.argv[1] d = Device(DEVICE_NAME) d.wakeup() os.system( "adb shell content insert --uri content://settings/system --bind name:s:user_rotation --bind value:i:0" ) while True: d.click(100, 100) time.sleep(5)
class ModelInfo(): ''' classdocs ''' def __init__(self, deviceserial): ''' Constructor ''' #sndLog = CLS("test", "test") self.osType = sys.platform self.mstrInfo = {} #self.devSerials = self.instAdb.device_serial() self.mstrDevice = Device(deviceserial) self.mstrInfo = self.mstrDevice.info ''' DEVICE Infoamtions { u'displayRotation': 0, u'displaySizeDpY': 640, u'displaySizeDpX': 360, u'currentPackageName': u'com.android.launcher', u'productName': u'takju', u'displayWidth': 720, u'sdkInt': 18, u'displayHeight': 1184, u'naturalOrientation': True } ''' def getCurrntProductInfo(self): return self.mstrInfo def getProductNmae(self): return self.mstrInfo['productName'] def getCurrntPkg(self): return self.mstrInfo['currentPackageName'] def getSDKInt(self): return self.mstrInfo['sdkInt'] def getRotation(self): return self.mstrInfo['displayRotation'] def getNaturalOri(self): return self.mstrInfo['naturalOrientation'] def getDisplayState(self): return self.mstrDevice.screen def setReflash(self): pass #define Key activity def setDevScrnOn(self): self.mstrDevice.screen.on() def setMstDevScrnOff(self): self.mstrDevice.screen.off() def setWakeup(self): self.mstrDevice.wakeup() def setSleep(self): self.mstrDevice.sleep() #Hard key Soft key def pressHome(self): return self.mstrDevice.press.home() def pressBack(self): return self.mstrDevice.press.back() ###################################################################### def pressLeft(self): return self.mstrDevice.press.left() def pressRight(self): return self.mstrDevice.press.right() def pressUp(self): return self.mstrDevice.press.up() def pressDown(self): return self.mstrDevice.press.down() def pressCenter(self): return self.mstrDevice.press.center() ###################################################################### def pressMenu(self): return self.mstrDevice.press.menu() def pressSearch(self): return self.mstrDevice.press.search() def pressEnter(self): return self.mstrDevice.press.enter() def pressDelete(self): return self.mstrDevice.press.delete() # or del def pressRecent(self): return self.mstrDevice.press.recent() def pressVol_Up(self): return self.mstrDevice.press.volume_up() def pressVol_Down(self): return self.mstrDevice.press.volume_down() def pressVol_Mute(self): return self.mstrDevice.press.volume_mute() def pressPower(self): return self.mstrDevice.press.power() def clik(self, x, y): return self.mstrDevice.click(x, y) def longClik(self,x, y): ''' Description: param: x, y : start first point x, y return : Boolean ''' return self.mstrDevice.long_click(x, y) def swipe(self, sx, sy, ex, ey, steps=10): ''' Description: param: sx, xy : start first x, y ex, ey : move to x, y return : Boolean ''' return self.mstrDevice.swipe(sx, sy, ex, ey, steps) def drage(self,sx, sy, ex, ey, steps=10): ''' Description: param: sx, xy : start first x, y ex, ey : move to x, y return : Boolean ''' return self.mstrDevice.drag(sx, sy, ex, ey, steps) #screen action of the device def setOrientation(self,scrAct='natural', choiceDevice='mstr'): ''' Description param d.orientation = 'l' or 'left' d.orientation = 'r' or 'right' d.orientation = 'n' or 'natural' return : None ''' self.mstrDevice.orientation = scrAct def setFreezeRotation(self,condition=False,choiceDevice='mstr'): ''' param: condition : False un-freeze rotation return : None ''' self.mstrDevice.freeze_rotation(condition) def takeScreenShot(self, choiceDevice = 'mstr'): ''' Description: take screenshot and save to local file 'home.png' can work until android 4.2 param image name ''' def dumpWindowHeirarchy(self,filename='./log/hierachy.xml'): return self.mstrDevice.dump(filename) def dumpWindowHeirarchyStream(self): return self.mstrDevice.dump() def notification(self): ''' Open notification, can not work until android 4.3 return : Boolean ''' return self.mstrDevice.open.Notification() def quickSettings(self): ''' open quick settins, can not work until android 4.3 return : Boolean ''' return self.mstrDevice.open.quick_settings() def waitidle(self): ''' wait for current window to idle return : None ''' self.mstrDevice.wait.idle() def waitWindowUpdate(self): ''' wait until window upate event occurs return : Boolean ''' self.mstrDevice.wait.update() def getCurrentActivityInfo(self, text): ''' INFOMATION: { u'contentDescription': u'', u'checked': False, u'scrollable': False, u'text': u'Settings', u'packageName': u'com.android.launcher', u'selected': False, u'enabled': True, u'bounds': {u'top': 385, u'right': 360, u'bottom': 585, u'left': 200}, u'className': u'android.widget.TextView', u'focused': False, u'focusable': True, u'clickable': True, u'chileCount': 0, u'longClickable': True, u'visibleBounds': {u'top': 385, u'right': 360, u'bottom': 585, u'left': 200}, u'checkable': False } ''' return self.mstrDevice(text).info def uiObjExist(self,text): ''' ture if exists, else False ''' return self.mstrDevice.exists(text) def watcher(self): pass def handler(self): pass def selector(self): pass def __del__(self): pass
class apptest(object): """docstring for apptest""" def __init__(self, app): super(apptest, self).__init__() self.app = app self.device = Device() self.app_name = self.app[0] self.app_path = self.app[1] self.app_package = self.get_package_name() self.app_activity = self.get_activity_name() #get function name def my_func_name(self): return inspect.stack()[1][3] #logout def logout(self, function_name, log_message): print ">>>%s:" % function_name + log_message #timeout def command_timeout(self, cmdline, timeout=60): p = subprocess.Popen(cmdline, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True) t_beginning = time.time() seconds_passed = 0 while True: if p.poll() is not None: return True seconds_passed = time.time() - t_beginning self.logout(self.my_func_name(), "Waiting.......%s (s)" % int(seconds_passed)) if timeout and seconds_passed > timeout: p.terminate() return False time.sleep(1) def screen_on(self): time.sleep(5) if self.device.screen == "off": self.logout(self.my_func_name(), "unlock screen...") self.device.wakeup() os.system("adb shell input keyevent 82") time.sleep(1) else: self.logout(self.my_func_name(), "Screen On.") def app_install(self): installed_app_package = self.get_installed_app_package() if installed_app_package == "": self.logout(self.my_func_name(), "Install %s" % self.app_name) try: os.system("adb install %s" % self.app_path) self.enable_3rd_market_app_install() time.sleep(2) except Exception, e: print e installed_app_package = self.get_installed_app_package() if installed_app_package != "": self.logout( self.my_func_name(), "Install completed, %s is found" % installed_app_package) else: self.logout( self.my_func_name(), "Install failed, %s not found" % installed_app_package) else:
import subprocess from uiautomator import Device import time d = Device('P2L4C17B27000826') x = subprocess.call("adb devices", shell=True) print("Return Code of adb command is : ", x) d.screen.on() time.sleep(2) coordinates = [] coordinates[0] = [205, 1343] coordinates[0] = [545, 1343] coordinates[0] = [847, 1343] coordinates[0] = [210, 1567] d.swipe(coordinates, 10) ''' # wakeup the device, same as turning on the screen. d.wakeup() # after 2 seconds turning off the screen time.sleep(2) # sleep the device, same as turning off the screen. d.sleep() ''' ''' # to perform screen on d.screen.on() # after 3 seconds turning off the screen time.sleep(3) # to perform screen off d.screen.off()
class Cases(unittest.TestCase): def setUp(self): self._driver = atx.connect() self._device = Device() def test_click(self): self._driver.click(540, 1650) self._driver.delay(2) self._driver.press.home() # self._driver.press("home") self._driver.delay(1) self._driver(description="Apps").click() self._driver.delay(1) self._driver.press.back() # self._driver.press("back") self._driver(text="Settings").long_click() def test_press(self): """press: home, back, left, right, up, down, center, menu, search, enter, delete(or del), recent, volume_up, volume_down, camera, power """ self._driver.press.volume_down() self._driver.delay(1) self._driver.press.volume_down() self._driver.delay(1) self._driver.press.volume_up() self._driver.delay(1) def test_screen(self): self._device.screen.off() self._driver.delay(2) self._device.screen.on() self._driver.delay(2) self._device.sleep() self._driver.delay(2) self._device.wakeup() def test_image(self): self._driver.start_app("com.android.calculator2") self._driver.delay(2) if self._driver.exists("1.jpg"): self._driver.click_image("1.jpg") self._driver.delay(1) else: print "Not find image" self._driver.screenshot("ttt.png") self._driver.stop_app("com.android.calculator2") def test_wait(self): if self._driver(text="1").wait.exists(timeout=10000): print "find it" if self._driver(text="1").wait.gone(timeout=10000): print "it gone" def test_child(self): self._driver(className="android.view.ViewGroup").child( text="Phone").click() self._driver.delay(1) self._driver.press("home") self._driver.delay(1) self._driver(text="Phone").click() self._driver.delay(1) self._driver.press("back") def test_instance(self): # count, instance # count = self._driver(className="android.widget.TextView").count # print count # self._driver(className="android.widget.TextView", instance=7).click() # self._driver.press.home() # self._driver.delay(1) # self._driver(className="android.widget.TextView")[7].click() # 计算器遍历 objs = self._driver(className="android.widget.Button") for obj in objs: obj.click() def test_set_text(self): # self._driver(resourceId="com.android.messaging:id/recipient_text_view").set_text("10086") # self._driver.delay(1) # self._driver.press.enter() # self._driver(resourceId="com.android.messaging:id/recipient_text_view").clear_text() # self._driver.delay(1) # self._driver.type("10086", enter=False) self._driver(resourceId="com.android.messaging:id/compose_message_text" ).long_click() def test_drag(self): self._driver(text="Settings").drag.to(950, 1000) self._driver.delay(1) self._driver(text="Settings").swipe.left(steps=100) def test_swipe(self): self._driver.swipe(1000, 1000, 500, 1000, steps=50) self._driver.delay(1) self._driver.swipe(500, 1000, 1000, 1000, steps=10) def test_scroll(self): self._driver(scrollable=True).scroll.to(text="Google") print "find it" def test_pinch(self): # com.google.android.apps.photos:id/list_photo_tile_view self._driver( resourceId="com.google.android.apps.photos:id/list_photo_tile_view" ).pinch.Out() self._driver.delay(1) self._driver( resourceId= "com.google.android.apps.photos:id/photo_hashtag_fragment_container" ).pinch.In() def test_cmd(self): dev = self._driver.adb_cmd("devices") mem = self._driver.adb_shell("dumpsys meminfo") print dev print mem def test_relative(self): self._driver(text="Cellular data").right( className="android.widget.Switch").click()
class UiAutomator(object): def __init__(self, serial=None): self.device = Device(serial) self.selector_mapping = {'text': 'text', 'id': 'resourceId', 'desc': 'description', 'class': 'className', 'index': 'index'} def do_action(self, **kwargs): action_name = kwargs.get('name').lower() if not action_name: return False elif action_name == 'press': return self.__press(**kwargs) elif action_name == 'click': return self.__click(**kwargs) elif action_name == 'random_click': return self.__random_click(**kwargs) elif action_name == 'edit': return self.__edit(**kwargs) elif action_name == 'wait': return self.__wait(**kwargs) elif action_name == 'wakeup': return self.__wakeup() elif action_name == 'sleep': return self.__sleep() elif action_name == 'objectinfo': return self.__get_object_info(**kwargs) elif action_name == 'orientation': return self.__orientation(**kwargs) elif action_name == 'get_current_package_name': return self.__get_current_package_name() elif action_name == 'open': return self.__open(**kwargs) elif action_name == 'exists': return self.__exists(**kwargs) elif action_name == 'return_to': return self.__return_to(**kwargs) def __get_selector(self, **kwargs): tmp = dict() for key in self.selector_mapping.keys(): parameter_value = kwargs.get(key) if parameter_value: tmp[self.selector_mapping.get(key)] = parameter_value return tmp def __click(self, **kwargs): selector = self.__get_selector(**kwargs) return self.device(**selector).click() def __exists(self, **kwargs): selector = self.__get_selector(**kwargs) return self.device(**selector).exists def __random_click(self, **kwargs): selector = self.__get_selector(**kwargs) count = self.device(**selector).count if count <= 0: return False selector['instance'] = randint(0, count-1) self.device(**selector).click() def __press(self, **kwargs): key = kwargs.get('key') if key in ["home", "back", "left", "right", "up", "down", "center", "menu", "search", "enter", "delete", "del", "recent", "volume_up", "volume_down", "volume_mute", "camera", "power"]: return self.device.press.__getattr__(key)() else: try: key_code = int(key) return self.device.press(key_code) except ValueError: return False def __open(self,**kwargs): key = kwargs.get('key') if key in ["notification", "quick_settings"]: return self.device.open.__getattr__(key)() return False def __orientation(self, **kwargs): # left/l: rotation=90 , displayRotation=1 # right/r: rotation=270, displayRotation=3 # natural/n: rotation=0 , displayRotation=0 # upsidedown/u: rotation=180, displayRotation=2 value = kwargs.get('value') if value in ['l', 'r', 'n', 'u', 'left', 'right', 'natural', 'upsidedown']: self.device.orientation = value return True return False def __freeze_rotation(self, **kwargs): value = kwargs.get('value', 'true') if value in ['False', 'false', 'f']: return self.device.freeze_rotation(freeze=False) return self.device.freeze_rotation(True) def __edit(self, **kwargs): selector = self.__get_selector(**kwargs) text_input = kwargs.get('input') return self.device(**selector).set_text(text=text_input) def __get_object_info(self, **kwargs): selector = self.__get_selector(**kwargs) key = kwargs.get('key') if key: return self.device(**selector).info.get(key) return self.device(**selector).info def __wait(self, **kwargs): try: wait_time = int(kwargs.get('time')) sleep(wait_time/1000.0) except ValueError: sleep(1) return True def __wakeup(self): return self.device.wakeup() def __sleep(self): return self.device.sleep() # def info(self): # return self.device.info # # def dump(self, filename=None, compressed=True, pretty=True): # Utility.output_msg('Dump device window and pull to \"%s\".' % filename) # return self.device.dump(filename=filename, compressed=compressed, pretty=pretty) # # def screenshot(self, filename, scale=1.0, quality=100): # Utility.output_msg('Take screenshot and save to \"%s\".' % filename) # return self.device.screenshot(filename=filename, scale=scale, quality=quality) # # # def long_click(self, **kwargs): # try: # return self.device(**kwargs).long_click() # except JsonRPCError, e: # return 'Error' # # def scroll(self, **kwargs): # return self.device(**kwargs).scroll(steps=steps) # def __get_current_package_name(self): return self.device.info.get('currentPackageName') def get_device_info(self): return self.device.info def __return_to(self, **kwargs): selector = self.__get_selector(**kwargs) for x in range(10): if self.device(**selector).exists: break self.device.press.back()
class UiTestLib(object): """Ui Test Lib """ def __init__(self, serial=None): """ """ logger.info("<p>Device=%s>" % serial, html=True) print "<p>Device=%s>" % serial self._result = "" self.starttime = 0 self.d = Device(serial) self.adb = Adb(serial) self.debug = "True" def set_debugable(flag): self.debug = flag def set_serial(self, serial): """Specify given *serial* device to perform test. or export ANDROID_SERIAL=CXFS42343 if you have many devices connected but you don't use this interface When you need to use multiple devices, do not use this keyword to switch between devices in test execution. And set the serial to each library. Using different library name when importing this library according to http://robotframework.googlecode.com/hg/doc/userguide/RobotFrameworkUserGuide.html?r=2.8.5. Examples: | Setting | Value | Value | Value | | Library | UiTestLib | WITH NAME | Mobile1 | | Library | UiTestLib | WITH NAME | Mobile2 | And set the serial to each library. | Test Case | Action | Argument | | Multiple Devices | Mobile1.Set Serial | device_1's serial | | | Mobile2.Set Serial | device_2's serial | """ self.d = Device(serial) self.adb = Adb(serial) def logmsg(self, msg): if self.debug == "True": print msg def exe_adb_command(self, cmd): """ Execute adb *cmd* Examples: | Exe Adb Command | shell getprop | """ return self.adb.cmd(cmd).wait() def exe_adb_and_result(self, cmd): """Execute adb *cmd* and return lines of the command""" lproc = self.adb.cmd(cmd) lproc.poll() lines = lproc.stdout.readlines() return lines def get_device_info(self): """Get Device information return info dictionary """ return self.d.info def light_screen(self): """Light screen by wakeup. Examples: | Action | |Light screen| Use `Light screen` to light screen. """ self.d.wakeup() self._result = self.d.press.home() def open_application(self, appname): """Open application by it name `appname`. Example: | Action | Argument | | Open application | "com.android.settings/com.android.settings.Settings" | """ appname = "shell am start -n " + appname print "Open Application:", appname self._result = self.exe_adb_command(appname) def click_text(self, text, instance=0): """Click text label on screen instance=0 is default, change when you needed. Example: | Action | Argument | Argument | | Click Text | text | instance | """ return self.d(text=text, instance=instance).click.wait() def long_click_text(self, text, instance=0): """ Long Click text label on screen, *text* and *instance=0* Example: | Action | Argument | Argument | | Long Click Text | text | instance | """ return self.d(text=text, instance=instance).long_click() def long_click_ui(self, **selectors): """ Long Click on **selectors** Selector supports below parameters. Refer to UiSelector java doc for detailed information. text, textContains, textMatches, textStartsWith className, classNameMatches description, descriptionContains, descriptionMatches, descriptionStartsWith checkable, checked, clickable, longClickable scrollable, enabled,focusable, focused, selected packageName, packageNameMatches resourceId, resourceIdMatches index, instance Example: | Action | Argument | Argument | Argument | | Long Click UI | text=XXXX | className=XXX.xxxx | resourceId=xxxxxx | """ return self.d(**selectors).long_click() def text_display_on_screen_contains(self, text): """Verify text display on screen Example: | Action | Argument | |Text display on screen is| text | """ if self.d(text=text).exists: self._result = True return True else: self._result = False return False def object_display_on_screen(self, obj, timeout=5000): """ Verify *obj* UiObject display on screen return to self._result Example: | Action | Argument | |Object display on screen | obj | """ if obj.wait.exists(timeout): self._result = True return True else: self._result = False return False def assert_expectation(self, expect, actual): """ Assert Expectation and actual value Example: | Action | args | args | | Assert Expectation | 324324 | ${actual} | """ if str(expect) != str(actual): raise AssertionError("Actual result is = %s, but expectation is: %s" % (str(actual), str(expect))) def assert_true(self, condition): """ Assert True of *condition Example: |Assert True | condition | """ if str(condition) != "True": # because only string from robotframework raise AssertionError("Result is = %s" % str(condition)) def assert_result_true(self): """ Assert True of *self._result Example: |Assert True | """ if self._result != True: raise AssertionError("Result is = %s" % str(self._result)) def wait_for_ui_exists(self, timeout, **selectors): """ Return True if Selector is to identify specific ui object in current window. # To seleted the object ,text is 'Clock' and its className is 'android.widget.TextView' wait_for_ui_exists(text='Clock', className='android.widget.TextView') Selector supports below parameters. Refer to UiSelector java doc for detailed information. text, textContains, textMatches, textStartsWith className, classNameMatches description, descriptionContains, descriptionMatches, descriptionStartsWith checkable, checked, clickable, longClickable scrollable, enabled,focusable, focused, selected packageName, packageNameMatches resourceId, resourceIdMatches index, instance Examples: | Action | Argument | Argument | Argument | Argument | |Wait For UI Exists | timeout | text=XXXX | className=XXX.xxxx | resourceId=xxxxxx | """ self._result = self.d(**selectors).wait.exists(timeout=int(timeout)) return self._result def wait_and_click(self, timeout, **selectors): """Wait for uiselector and click""" if self.d(**selectors).wait.exists(timeout=int(timeout)): self.d(**selectors).click() def assert_ui_exists(self, **selectors): """ Assert UiObject appear on the screen Examples: | Action | Argument | Argument | Argument | Argument | |Assert UI Exists | timeout | text=XXXX | className=XXX.xxxx | resourceId=xxxxxx | """ if not self.d(**selectors).wait.exists(): raise AssertionError("UiObject does not exists %s" % selectors.items()) def result_should_be(self, expected): """Verifies that the current result is `expected`. Example: | Action | Argument | | Open application | com.android.settings/com.android.settings.Settings | | Result Should Be | 0 | """ print ("result is: %s\n", self._result) print ("ex is: %s\n", expected) if str(self._result) != expected: raise AssertionError("%s != %s" % (self._result, expected)) def click_at_coordinates(self, x, y): """ Click at (x,y) coordinates. Example: | Action | Argument | Argument | | Click At Corrdinates | x | y | """ return self.d.click(int(x), int(y)) def long_click_at_coordinates(self, x, y): """ # long click (x, y) on screen """ return self.d.long_click(int(x), int(y)) def swipe(self, sx, sy, ex, ey, steps=20): """ Swipe from (sx,sy) to (ex,ey) """ return self.d.swipe(int(sx), int(sy), int(ex), int(ex), int(steps)) def drag(self, sx, sy, ex, ey, steps=20): """ Drag from (sx,sy) to (ex,ey) """ return self.d.drag(int(sx), int(sy), int(ex), int(ex), int(steps)) def freeze_rotation(self, rotation=True): """ Freeze rotation, *rotation*, True is default, """ return self.d.freeze_rotation(rotation) def set_rotation(self, rotation): """ # retrieve orientation, # it should be "natural" or "left" or "right" or "upsidedown" Example: | Action | Argument | | Set Rotation | nature | | Set Rotation | left | | Set Rotation | right | | Set Rotation | upsidedown | """ orientation = self.d.orientation if rotation == "nature": self.d.orientation = "n" # or "natural" elif rotation == "left": self.d.orientation = "l" # or "left" elif rotation == "right": self.d.orientation = "r" # or "right" elif rotation == "upsidedown": self.d.orientation = "upsidedown" # or "upsidedown" else: self.d.rotation = "n" def take_screenshot(self, scale=None, quality=None): """ Take a screenshot of device and log in the report with timestamp, scale for screenshot size and quality for screenshot quality default scale=1.0 quality=100 Example: | Action | Argument | Argument | | Take Screenshot | 0.5 | 80 | """ output_dir = BuiltIn().get_variable_value("${OUTPUTDIR}") ts = time.time() st = datetime.datetime.fromtimestamp(ts).strftime("%Y%m%d%H%M%S") screenshot_path = "%s%s%s.png" % (output_dir, os.sep, st) screenshot_name = "%s%s.png" % (os.sep, st) self.d.screenshot(screenshot_path, scale, quality) logger.info('\n<a href="%s">%s</a><br><img src="%s">' % (screenshot_path, st, screenshot_name), html=True) def open_notification(self): """ Open notification of the phone """ self.d.open.notification() def wait_window_update(self): """ wait for window update """ return self.d.wait.update() def wait_window_idle(self): """ wait for window idle """ return self.d.wait.idle() def remove_watchers(self): """ Remove UI watchers """ self.d.watchers.remove() def get_device(self): """ Get device object, you can do any command using this """ return self.d def click_id(self, id, instance=0): """ Click *id* with *instance*=0 """ return self.d(resourceId=id, instance=instance).click.wait() def long_click_id(self, id, instance=0): """ Long click *id* with *instance*=0 """ return self.d(resourceId=id, instance=0).long_click() def click_description(self, description, instance=0): """ Click *description* with *instance*=0 """ return self.d(description=description, instance=instance).long_click() def click_class(self, className, instance=0): """ Click *className* with *instance*=0 """ return self.d(className=className, instance=instance).long_click() def type_text(self, textStr, **selectors): """ type text on selectors like text=EditName """ self.d(**selectors).set_text(textStr) def press_key(self, key): """ Press Key of following value home back left right up down center menu search enter delete(or del) recent(recent apps) volume_up volume_down volume_mute camera power Examples: | Action | Argument | | Press Key | home | | Press Key | back | | Press Key | left | | Press Key | right | | Press Key | recent | | Press Key | volume_up | | Press Key | camera | """ if key.isdigit(): return self.d.press(int(key)) return self.d.press(key) def phone_sleep(self, timeout): """ android device sleep with timeout in ms, don't use for executor sleep, """ return self.d.wait(int(timeout)) def execute_command(self, cmd, block_parent_process=True): """ Execute shell *cmd* command, with block_parent_process = True If block_parent_process = False, kill_command is needed to terminal the child process Example: | Execute Command | ping -c 5 127.0.0.1 | """ if str(block_parent_process) == str(True): return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() else: return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) def kill_command(self, process, timeout=0): """ Kill child *process* in timeout seconds Some bugs after process teminated """ time.sleep(float(timeout)) process.terminate() def wait_for_logcat(self, log, timeout=30): """ Wait log exists in given timeout, return True if have, otherwise will return False log is your want to search, log can be a regular expression time in seconds, default value is 30 seconds Example: | Wait For Logcat | .*ActivityManager.*cmp=com.sonyericsson.album/com.sonyericsson.album.Main.* | """ start = time.time() while (time.time() - start) < int(timeout): log_proc = self.adb.cmd("logcat -d -v time") returncode = log_proc.poll() lines = log_proc.stdout.readlines() for line in lines: rlt = re.search(log, line.rstrip()) if rlt is not None: print rlt.group(0) self._result = True return True time.sleep(2) # sleep 2s to wait self._result = False return False def clear_logcat(self): """ Clear logcat, it's often used before you want to use *wait_for_logcat()* """ print "Clear logcat before test" return self.exe_adb_command("logcat -c") def click_object(self, obj): """ Click UiObject *obj* Exmaple: | ${result} | Get UI Object | text=XXX | className=xxxx | | Click Object | ${result} | """ obj.click() def click_ui(self, **selectors): """ Click selector click_selector(text="Home", resourceId = "android:id/title") for **selector, please refer *get_ui_object()* Selector supports below parameters. Refer to UiSelector java doc for detailed information. text, textContains, textMatches, textStartsWith className, classNameMatches description, descriptionContains, descriptionMatches, descriptionStartsWith checkable, checked, clickable, longClickable scrollable, enabled,focusable, focused, selected packageName, packageNameMatches resourceId, resourceIdMatches index, instance Operation for a UiObjects: click, clear_text, drag(obj).to(**selector), gesture, exists, set_text, long_click pinch.In(percent=100, steps=10), pinch.Out(percent=100, steps=100),.swipe.right(), .swipe.left(steps=10),.swipe("right", steps=20),.wait.gone(),.wait.exists() """ print "selectors:", selectors return self.d(**selectors).click() def get_ui_object(self, **selectors): """ Get UI object with *selectors* you can do anything on UiObject, like click(), long_click(),wait.exists(timeout) examples: get_ui_object(text="Home", resourceId = "android:id/title") Selector supports below parameters. Refer to UiSelector java doc for detailed information. text, textContains, textMatches, textStartsWith className, classNameMatches description, descriptionContains, descriptionMatches, descriptionStartsWith checkable, checked, clickable, longClickable scrollable, enabled,focusable, focused, selected packageName, packageNameMatches resourceId, resourceIdMatches index, instance Operation for a UiObjects: click, clear_text, drag(obj).to(**selector), gesture, exists, set_text, long_click pinch.In(percent=100, steps=10), pinch.Out(percent=100, steps=100),.swipe.right(), .swipe.left(steps=10),.swipe("right", steps=20),.wait.gone(),.wait.exists() Exmaple: | ${result} | Get UI Object | text=XXX | className=xxxx | """ self._result = self.d(**selectors) return self._result def wait_for_object_exists(self, obj, timeout=0): """ Wait for UiObject *obj* exists in *timeout*= 0 Example: | ${result} | Get UI Object | text=XXX | className=xxxx | | Wait For Object Exists | ${result} | timeout | """ self._result = obj.wait.exists(timeout=int(timeout)) return self._result def wait_for_ui_gone(self, timeout=0, **selectors): """ Wait for UiObject *obj* gone in *timeout*= 0 Example: | ${result} | Get UI Object | text=XXX | className=xxxx | | Wait For Object Gone | ${result} | timeout | """ self._result = self.d(**selectors).wait.gone(timeout=int(timeout)) return self._result def get_key_value(self, key, dictionary): """ Get key value of dictionary """ return dictionary(key) def get_tts(self, input_text, delete_file=False, **args): """ Get TTS voice mp3 from Google get_tts(input_text='tunnel snakes rule apparently', args = {'language':'en','output':'outputto.mp3'}) Robot Framework: Examples: | Action | Argument | Argument | Argument | Argument | | UiTestLib.Get TTS | Hello world | False | output=ooo.mp3 | language=en | """ print "Get text to speech: ", input_text downloaded = False if str(delete_file) == "True": if os.path.exists(args["output"]): os.remove(args["output"]) if os.path.exists(args["output"]): if os.path.getsize(args["output"]) <= 0: os.remove(args["output"]) if args["output"] is not None: if not os.path.exists(args["output"]): print "Generating mp3 file......", args["output"] downloaded = GoogleTTS.audio_extract(input_text, args) else: print "Have same local file" downloaded = True if not downloaded: print "Downloaded TTS from Google failed, trying to download from local FTP..." mp3file = open(args["output"], "w") mp3url = "ftp://cnbjlx9548/atautomation/Test-Content/Croft/" + args["output"] try: resp = urllib2.urlopen(mp3url, timeout=40) mp3file.write(resp.read()) time.sleep(0.05) except Exception, e: print e return False mp3file.close() return True
class ModelInfo(): ''' classdocs ''' def __init__(self, deviceserial): ''' Constructor ''' #sndLog = CLS("test", "test") self.osType = sys.platform self.mstrInfo = {} #self.devSerials = self.instAdb.device_serial() self.mstrDevice = Device(deviceserial) self.mstrInfo = self.mstrDevice.info ''' DEVICE Infoamtions { u'displayRotation': 0, u'displaySizeDpY': 640, u'displaySizeDpX': 360, u'currentPackageName': u'com.android.launcher', u'productName': u'takju', u'displayWidth': 720, u'sdkInt': 18, u'displayHeight': 1184, u'naturalOrientation': True } ''' def getCurrntProductInfo(self): return self.mstrInfo def getProductNmae(self): return self.mstrInfo['productName'] def getCurrntPkg(self): return self.mstrInfo['currentPackageName'] def getSDKInt(self): return self.mstrInfo['sdkInt'] def getRotation(self): return self.mstrInfo['displayRotation'] def getNaturalOri(self): return self.mstrInfo['naturalOrientation'] def getDisplayState(self): return self.mstrDevice.screen def setReflash(self): pass #define Key activity def setDevScrnOn(self): self.mstrDevice.screen.on() def setMstDevScrnOff(self): self.mstrDevice.screen.off() def setWakeup(self): self.mstrDevice.wakeup() def setSleep(self): self.mstrDevice.sleep() #Hard key Soft key def pressHome(self): return self.mstrDevice.press.home() def pressBack(self): return self.mstrDevice.press.back() ###################################################################### def pressLeft(self): return self.mstrDevice.press.left() def pressRight(self): return self.mstrDevice.press.right() def pressUp(self): return self.mstrDevice.press.up() def pressDown(self): return self.mstrDevice.press.down() def pressCenter(self): return self.mstrDevice.press.center() ###################################################################### def pressMenu(self): return self.mstrDevice.press.menu() def pressSearch(self): return self.mstrDevice.press.search() def pressEnter(self): return self.mstrDevice.press.enter() def pressDelete(self): return self.mstrDevice.press.delete() # or del def pressRecent(self): return self.mstrDevice.press.recent() def pressVol_Up(self): return self.mstrDevice.press.volume_up() def pressVol_Down(self): return self.mstrDevice.press.volume_down() def pressVol_Mute(self): return self.mstrDevice.press.volume_mute() def pressPower(self): return self.mstrDevice.press.power() def clik(self, x, y): return self.mstrDevice.click(x, y) def longClik(self, x, y): ''' Description: param: x, y : start first point x, y return : Boolean ''' return self.mstrDevice.long_click(x, y) def swipe(self, sx, sy, ex, ey, steps=10): ''' Description: param: sx, xy : start first x, y ex, ey : move to x, y return : Boolean ''' return self.mstrDevice.swipe(sx, sy, ex, ey, steps) def drage(self, sx, sy, ex, ey, steps=10): ''' Description: param: sx, xy : start first x, y ex, ey : move to x, y return : Boolean ''' return self.mstrDevice.drag(sx, sy, ex, ey, steps) #screen action of the device def setOrientation(self, scrAct='natural', choiceDevice='mstr'): ''' Description param d.orientation = 'l' or 'left' d.orientation = 'r' or 'right' d.orientation = 'n' or 'natural' return : None ''' self.mstrDevice.orientation = scrAct def setFreezeRotation(self, condition=False, choiceDevice='mstr'): ''' param: condition : False un-freeze rotation return : None ''' self.mstrDevice.freeze_rotation(condition) def takeScreenShot(self, choiceDevice='mstr'): ''' Description: take screenshot and save to local file 'home.png' can work until android 4.2 param image name ''' def dumpWindowHeirarchy(self, filename='./log/hierachy.xml'): return self.mstrDevice.dump(filename) def dumpWindowHeirarchyStream(self): return self.mstrDevice.dump() def notification(self): ''' Open notification, can not work until android 4.3 return : Boolean ''' return self.mstrDevice.open.Notification() def quickSettings(self): ''' open quick settins, can not work until android 4.3 return : Boolean ''' return self.mstrDevice.open.quick_settings() def waitidle(self): ''' wait for current window to idle return : None ''' self.mstrDevice.wait.idle() def waitWindowUpdate(self): ''' wait until window upate event occurs return : Boolean ''' self.mstrDevice.wait.update() def getCurrentActivityInfo(self, text): ''' INFOMATION: { u'contentDescription': u'', u'checked': False, u'scrollable': False, u'text': u'Settings', u'packageName': u'com.android.launcher', u'selected': False, u'enabled': True, u'bounds': {u'top': 385, u'right': 360, u'bottom': 585, u'left': 200}, u'className': u'android.widget.TextView', u'focused': False, u'focusable': True, u'clickable': True, u'chileCount': 0, u'longClickable': True, u'visibleBounds': {u'top': 385, u'right': 360, u'bottom': 585, u'left': 200}, u'checkable': False } ''' return self.mstrDevice(text).info def uiObjExist(self, text): ''' ture if exists, else False ''' return self.mstrDevice.exists(text) def watcher(self): pass def handler(self): pass def selector(self): pass def __del__(self): pass
class UiTestLib(object): """Ui Test Lib """ def __init__(self, serial = None): """ """ logger.info('<p>Device=%s>' % serial, html=True) print '<p>Device=%s>' % serial self._result = '' self.starttime = 0 self.d = Device(serial) self.adb = Adb(serial) self.debug = 'True' def set_debugable(self, flag): self.debug = flag def set_serial(self, serial): """Specify given *serial* device to perform test. or export ANDROID_SERIAL=CXFS42343 if you have many devices connected but you don't use this interface When you need to use multiple devices, do not use this keyword to switch between devices in test execution. And set the serial to each library. Using different library name when importing this library according to http://robotframework.googlecode.com/hg/doc/userguide/RobotFrameworkUserGuide.html?r=2.8.5. Examples: | Setting | Value | Value | Value | | Library | UiTestLib | WITH NAME | Mobile1 | | Library | UiTestLib | WITH NAME | Mobile2 | And set the serial to each library. | Test Case | Action | Argument | | Multiple Devices | Mobile1.Set Serial | device_1's serial | | | Mobile2.Set Serial | device_2's serial | """ self.d = Device(serial) self.adb = Adb(serial) def logmsg(self, msg): if self.debug == 'True': print msg def exe_adb_command(self, cmd): """ Execute adb *cmd* Examples: | Exe Adb Command | shell getprop | """ return self.adb.cmd(cmd).wait() def exe_adb_and_result(self, cmd): """Execute adb *cmd* and return lines of the command""" lproc = self.adb.cmd(cmd) lproc.poll() lines = lproc.stdout.readlines() return lines def get_device_info(self): """Get Device information return info dictionary """ return self.d.info def light_screen(self): """Light screen by wakeup. Examples: | Action | |Light screen| Use `Light screen` to light screen. """ self.d.wakeup() self._result = self.d.press.home() def open_application(self, appname): """Open application by it name `appname`. Example: | Action | Argument | | Open application | "com.android.settings/com.android.settings.Settings" | """ if appname.find('/') > 0: appname = 'shell am start -n ' + appname else: appname = 'shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER ' + appname print 'Open Application:', appname self._result = self.exe_adb_command(appname)