class contacts: ''' contacts class ''' def __init__(self, device, devID='emulator-5554',sample = False): ''' constructor @type device: MonkeyDevice @param device: The device or emulator connected @type devID: str @param serialno: the serial number of the device or emulator to connect to @type sample: boolean @param sample: whether take snapshot as an sampling ''' self.device=device self.sample=sample self.contactCounter=0 self.startStatus=False '''the status which indicate whether the contacts activity is started''' #use below code to remove the status bar from the snapshot width = int(device.getProperty('display.width')) height = int(device.getProperty('display.height')) density = device.getProperty('display.density') if density == .75: statusBarHeight = 19 elif density == 1.5: statusBarHeight = 38 elif density == 2.0: statusBarHeight = 50 else: statusBarHeight = 25 self.snap_rect = 0, statusBarHeight, width, height - statusBarHeight #define the point coordinate used to slide screen self.left = (width/4, height/2) self.right = (width/4*3, height/2) self.up = (width/2, height/4) self.down = (width/2, height/4*3) self.center = (width/2, height/2) trace('before instance') self.vc=ViewClient(device, devID) trace('after instance') def start(self): ''' start the contacts activity and set the startStatus True if contacts is ready. ''' trace('Starting activity ...') self.device.startActivity(component=componentName) sleep(2) self.startStatus = self.goList() trace('Contacts is started, checking the contacts status...') self.isReady() sleep(2) def stop(self): ''' stop the contacts activity and set the startStatus False ''' self.device.shell('am force-stop %s' % package) trace('force stop contacts package %s' % package) self.startStatus = False def back(self): ''' press back ''' self.device.press('KEYCODE_BACK','DOWN_AND_UP') trace('press back') def slide(self,str): ''' slide the screen @type: str @param: 'left','right','up','down' ''' if str not in ['left','right','up','down']: raise SyntaxError("wrong parameter: choose from 'left','right','up' or 'down'") nav = { 'left':{'start':self.right,'end':self.left}, 'right':{'start':self.left,'end':self.right}, 'up':{'start':self.down,'end':self.up}, 'down':{'start':self.up,'end':self.down} } self.device.drag(nav[str]['start'], nav[str]['end'], 0.1, 1) trace('slide the screen from %s to %s ' % (nav[str]['start'],nav[str]['end'])) sleep(2) def getView(self,str,cD=False,iD=False,dump=True,regex=False): ''' get the view with the specified text, content description or viewId @type str: str @param str: the query string @type cD: boolean @param cD: whether handle the query str as content description @type iD: boolean @param iD: whether handle the query str as viewId @type dump: boolean @param dump: whether execute dump before findView, depending on whether the screen is changed @return: the view found ''' if dump: trace('before dump') self.vc.dump() trace('after dump') if cD: view=self.vc.findViewWithContentDescription(str) trace('Query view with content description: %s, return is %s' % (str, view is not None)) return view elif iD: view=self.vc.findViewById(str) trace('Query view by id: %s, return is %s' % (str, view is not None)) return view elif regex: view=self.vc.findViewWithAttributeThatMatches('text',re.compile(str)) trace('Query view that match attribute: %s, return is %s' % (str, view is not None)) return view else: view=self.vc.findViewWithText(str) trace('Query view with text: %s, return is %s ' % (str, view is not None)) return view def isReady(self): ''' check whether the contacts is ready. @return: True ''' while True: view=self.getView('Contacts list is being updated to reflect the change of language.') if not view: trace('Contacts is ready') break else: trace('Contacts is not ready, please wait!') sleep(2) return True def isEmpty(self): ''' check whether the contacts is empty @return: True or False ''' self.check() view=self.getView('No contacts.') if view: trace('Contacts list is empty') return True else: trace('Contacts list is not empty') return False def getCounter(self): ''' get the contacts counter @return: the current contacts counter ''' self.goList() if self.isEmpty(): self.contactCounter=0 else: while not self.getView('\d+ contacts?',regex=True): self.slide('down') sleep(3) self.contactCounter = int(self.getView('\d+ contacts?',regex=True,dump=False).getText().split()[0]) trace('current contacts counter is %d' % self.contactCounter) return self.contactCounter def goList(self): ''' check whether the screen is in contacts list view, if not, go list view via pressing back key @return: True ''' while True: view=self.getView("All contacts",cD=True) if not view: self.back() sleep(3) else: if not view.isSelected(): trace('Touch "All contacts"') view.touch() break trace('Goto contacts list view') return True def goEdit(self): ''' check whether the contacts is empty, then select adding and go to edit view. @return: True ''' self.check() try: self.getView('Add Contact',cD=True,dump=False).touch() trace('Touch "Add Contact"') sleep(5) return True except AttributeError: pass try: self.getView('Create a new contact',dump=False).touch() trace('Touch "Create a new contact"') sleep(5) self.getView('Keep local').touch() trace('Select "Keep local"') sleep(5) return True except AttributeError: pass def check(self): ''' check whether the contacts is started before other operation about contacts @return: True ''' if not self.startStatus: trace("Wrong code! please start contacts firstly in you code") raise SyntaxError('contacts should be start firstly!') return True def snapshot(self,title): ''' take snapshot @type title: str @param title: specify the title of snapshot @return: snapshot object ''' snapName = title + '.png' snapFolder = 'snapshot' os.system('if not exist %s\\%s mkdir %s\\%s' % (logPath, snapFolder, logPath, snapFolder)) snapFile = logPath + '\\' + snapFolder + '\\' + snapName result = self.device.takeSnapshot().getSubImage(self.snap_rect) trace('take snapshot without the statusbar') result.writeToFile(snapFile,'png') trace('save the snapshot to file: %s ' % snapFile) return result def wipe(self,view): ''' wipe the text in specified view ''' try: self.device.drag(view.getXY(),view.getXY(),1,1) trace('wipe text: %s' % str(view.getText())) self.device.press('KEYCODE_DEL','DOWN_AND_UP') except: Exception('wipe failed') def addContact(self,name='',phone='',email='',address=''): self.goEdit() try: offset = 0 if name: view=self.getView('id/no_id/27',iD=True) trace('type %s' % name) view.type(name) view.touch() if phone: view=self.getView('id/no_id/46',iD=True,dump=False) trace('type %s' % phone) view.type(phone) offset += 4 sleep(2) if email: view=self.getView('id/no_id/' + str(57 + offset), iD=True) trace('type %s' % email) view.type(email) offset += 4 sleep(2) if address: view=self.getView('id/no_id/' + str(68 + offset), iD=True) trace('type %s' % address) view.type(address) sleep(2) view=self.getView('Done',dump=False) view.touch() trace('Touch Done') finally: sleep(5) self.goList() def goEditExistContact(self,str): trace('Search a contact to edit') view=self.search(str) if not view: raise SyntaxError('No '+str+' contact to edit') view.touch() sleep(4) self.device.press('KEYCODE_MENU') sleep(2) self.device.press('KEYCODE_DPAD_DOWN') sleep(1) self.device.press('KEYCODE_ENTER') sleep(3) def slideByView(self,view): trace('SlideByView') startp=(view.getX()+view.getWidth()-10,view.getY()+view.getHeight()-10) endpoint=(view.getX()+view.getWidth()-10,view.getY()+10) self.device.drag(startp,endpoint,0.5,1) sleep(1) def editCompany(self,company,action): view=self.getView('Add organization') if view: trace('Step: add a organization info') view.touch() sleep(1) trace('add the company info') self.device.type(company) sleep(1) view=self.getView('Title') trace("add a company's Title") view.type(company) else: trace('Step: Edit the organization info') view=self.getView('id/no_id/42',iD=True) self.wipe(view) trace('Edit the company info') self.device.type(company) view=self.getView('id/no_id/43',iD=True) trace("Edit the company's Title") self.wipe(view) self.device.type(company) def editAnotherField(self,fieldName,content,action): find=1 view=self.getView(fieldName) view2=self.getView('Add another field') while not view: self.device.drag((440,760),(440,160),2,5) sleep(1) view=self.getView(fieldName) view2=self.getView('Add another field') if view2: if not view: find=0 break if 0==find: trace('Step: add field '+fieldName+' info') view2.touch() trace('Click Add another field') sleep(2) view=self.getView(fieldName) if not view: view2=self.getView('id/no_id/2',iD=True) self.slideByView(view2) view=self.getView(fieldName) view.touch() sleep(1) #view=self.getView(fieldName) #view2=self.getView(view.getId()[:-2]+str(int(view.getId()[-2:])+6),iD=True) #view2.type(content) sleep(1) self.device.type(content) sleep(2) else: trace('Step: Edit field '+fieldName+' info') view2=self.getView(view.getId()[:-2]+str(int(view.getId()[-2:])+6),iD=True) self.wipe(view2) sleep(1) view2.type(content) sleep(1) def editDetails(self,nameOrNumber,company='',website='',nickname='',notes='',action='add'): ''' ''' self.goEditExistContact(nameOrNumber) if not company=='': self.editCompany(company,action) if not website=='': self.editAnotherField('Website',website,action) if not nickname=='': self.editAnotherField('Nickname',nickname,action) if not website=='': self.editAnotherField('Notes',notes,action) view=self.getView('Done') trace('Click Done') view.touch() sleep(3) self.goList() def search(self,str): ''' @type str: str @param str: specify the search keyword ##@return: the view of search result if search result is not null, else return None ''' trace("start searching...") self.goList() searchView=self.getView("Search",True) searchView.touch() sleep(2) self.device.type(str) trace("search keyword is: "+str) #the id of 1st search result is always 28 if self.getView("No contacts"): trace("No contact searched") return None else: return self.getView("id/no_id/28",iD=True) def sortAndViewAs(self, sortByFirstName=True, viewAsFirstNameFirst=True): ''' sort contact name @type sortByFirstName: boolean @param sortByFirstName: whether sort contact name by first name @type viewAsFirstNameFirst: boolean @param viewAsFirstNameFirst: whether view contact by first name first ''' self.goList() trace("start sorting...") self.device.press("KEYCODE_MENU","DOWN_AND_UP") settingsView=self.getView("Settings") settingsView.touch() sleep(2) self.getView("Sort list by").touch() if sortByFirstName: self.getView("First name").touch() sleep(2) self.getView("View contact names as").touch() sleep(2) if viewAsFirstNameFirst: self.getView("First name first").touch() else: self.getView("Last name first").touch() else: self.getView("Last name").touch() sleep(2) self.getView("View contact names as").touch() sleep(2) if viewAsFirstNameFirst: self.getView("First name first").touch() else: self.getView("Last name first").touch() sleep(2) def favor(self,str,favor=True): ''' add or cancel contact to favorites @type str: str @param str: specify the search string @type favor: boolean @param favor: add if True ''' try: self.search(str).touch() sleep(3) except AttributeError: trace('no matched contact found, operation failed!') self.goList() return False aim, action = ('Add to favorites', 'add') if favor else ('Remove from favorites', 'remov') try: self.getView(aim, cD=True).touch() trace('%s successfully' % aim) except AttributeError: trace('%s has been %sed in favorites, not have to %s repeatedly' % (str, action, action)) sleep(3) self.goList() return True def delete(self,kwd = ''): '''delete one contact @type kwd: string @param kwd: keyword which contact to be delete, if none,delete first contact @return: ''' #self.start() #trace('launch on contact application') self.goList() if self.isEmpty(): trace('Could not find any contact data,no record!') raise SyntaxError('Could not find any contact data,no record!') if not kwd : # keyword is empty,delete first contact trace('keyword is none, first contact with be delete') find = self.getView('id/no_id/27',iD=True,dump=False) #if find != None: else : # keyword is not none # search specifying contact by keyword find = self.search(kwd) trace('') # if find != None: if not find : trace('Could not find the contact : ' + kwd) raise SyntaxError('Could not find the contact : ' + kwd) else: # delete operate find.touch() sleep(3) trace('show contact detail information') sleep(1) self.device.press('KEYCODE_MENU') sleep(4) delete_menu = self.getView('Delete') trace('choose delete contact') delete_menu.touch() # confirm delete operate ok_menu = self.getView('OK') ok_menu.touch() sleep(3) # if current activity is not Main Activity back to Main Activity self.goList() if 0 == self.getCounter() : trace(' all contacts has been deleted, no record!') trace('operation success.')
class contacts: ''' contacts class ''' def __init__(self, device, devID='emulator-5554', sample=False): ''' constructor @type device: MonkeyDevice @param device: The device or emulator connected @type devID: str @param serialno: the serial number of the device or emulator to connect to @type sample: boolean @param sample: whether take snapshot as an sampling ''' self.device = device self.sample = sample self.startStatus = False '''the status which indicate whether the contacts activity is started''' self.vc = ViewClient(device, devID) #use below code to remove the status bar from the snapshot width = int(device.getProperty('display.width')) height = int(device.getProperty('display.height')) density = device.getProperty('display.density') if density == .75: statusBarHeight = 19 elif density == 1.5: statusBarHeight = 38 elif density == 2.0: statusBarHeight = 50 else: statusBarHeight = 25 self.snap_rect = 0, statusBarHeight, width, height - statusBarHeight def start(self): ''' start the contacts activity and set the startStatus True if contacts is ready. ''' self.device.startActivity(component=componentName) sleep(3) self.startStatus = self.isReady() def back(self): ''' press back ''' self.device.press('KEYCODE_BACK', 'DOWN_AND_UP') def getView(self, str, cD=False, iD=False): ''' get the view with the specified text, content description or viewId @type str: str @param str: the query string @type cD: boolean @param cD: whether handle the query str as content description @type iD: boolean @param iD: whether handle the query str as viewId @return: the view found ''' self.vc.dump() sleep(3) if not cD: if not iD: return self.vc.findViewWithText(str) else: return self.vc.findViewById(str) else: return self.vc.findViewWithContentDescription(str) def isReady(self): ''' check whether the contacts is ready. ''' while True: view = self.getView( 'Contact list is being updated to reflect the change of language.' ) if not view: trace('Contacts is ready') break else: trace('Contacts is not ready, please wait!') sleep(2) return True def goEdit(self): ''' check whether the contact is empty, then select adding and go to edit view. @return: True ''' self.check() view = self.getView('Create a new contact') if view: view.touch() trace('Click "Create a new contact"') view = self.getView('Keep local') if view: view.touch() trace('Select "Keep local"') else: view = self.getView('Add Contact', True) view.touch() trace('Click "Add Contact"') return True def check(self): ''' check whether the contacts is started before other operation about contacts @return: True ''' if not self.status: trace("Wrong code! please start contacts firstly in you code") raise SyntaxError('contacts should be start firstly!') return True def snapshot(self, title): ''' take snapshot @type title: str @param title: specify the title of snapshot ''' snapName = title + '.png' snapFile = logPath + '\\' + snapName result = self.device.takeSnapshot().getSubImage(self.snap_rect) result.writeToFile(snapFile, 'png') def addContact(self, name='', phone='', email=''): #notice firstly call self.goEdit() pass def editDetails(self, phone=''): pass def search(self, str): ''' @type str: str @param str: specify the search keyword ##@return: the view of search result if search result is not null, else return None ''' trace("start searching...") trace("check contact main UI, dump, please wait...") self.vc.dump() while not self.getView("Search", True): self.device.press('KEYCODE_BACK') sleep(2) self.vc.dump() searchView = self.getView("Search", True) searchView.touch() self.device.type(str) trace("search keyword is: " + str) self.snapshot("search_result") ''' tmp=[] self.vc.dump() trace("dump, please wait...") #the id of 1st search result is always 28 for i in self.vc.findViewsContainingPoint((100,200)): tmp.append(i.getId()) result=int(tmp[len(tmp)-1][-2:]) if(result<28): trace("search result: nothing") return None else: self.snapshot("search_result") return self.vc.findViewById(tmp[len(tmp)-1]) ''' def sortAs(self, sortByFirstName=True): ''' sort contact name @type sortByFirstName: boolean @param sortByFirstName: whether sort contact name by first name ''' trace("check contact main UI, dump, please wait...") self.vc.dump() while not self.getView("Search", True): self.device.press('KEYCODE_BACK') sleep(2) self.vc.dump() trace("start sorting...") self.device.press("KEYCODE_MENU", "DOWN_AND_UP") trace("click menu, dump, please wait...") self.vc.dump() settingsView = self.getView("Settings") settingsView.touch() sleep(2) trace("click Settings, dump, please wait...") self.vc.dump() self.vc.findViewWithTextOrRaise("Sort list by").touch() trace("click Sort list by, dump, please wait...") self.vc.dump() if sortByFirstName: self.vc.findViewWithTextOrRaise("First name").touch() else: self.vc.findViewWithTextOrRaise("Last name").touch() sleep(2) #conflict with check at the begining #self.device.press("KEYCODE_BACK","DOWN_AND_UP") #sleep(2) def viewAs(self, viewAsFirstNameFirst=True): ''' view contact name @type viewAsFirstNameFirst: boolean @param viewAsFirstNameFirst: whether view contact by first name first ''' trace("check contact main UI, dump, please wait...") self.vc.dump() while not self.getView("Search", True): self.device.press('KEYCODE_BACK') sleep(2) self.vc.dump() trace("start viewing...") self.device.press("KEYCODE_MENU", "DOWN_AND_UP") trace("click menu, dump, please wait...") self.vc.dump() settingsView = self.getView("Settings") settingsView.touch() sleep(2) trace("click Settings, dump, please wait...") self.vc.dump() self.vc.findViewWithTextOrRaise("View contact names as").touch() trace("click View contact names as, dump, please wait...") self.vc.dump() if viewAsFirstNameFirst: self.vc.findViewWithTextOrRaise("First name first").touch() else: self.vc.findViewWithTextOrRaise("Last name first").touch() sleep(2) #conflict with check at the begining #self.device.press("KEYCODE_BACK","DOWN_AND_UP") #sleep(2) def favorite(self, name=''): pass
class contacts: ''' contacts class ''' def __init__(self, device, devID='emulator-5554', sample=False): ''' constructor @type device: MonkeyDevice @param device: The device or emulator connected @type devID: str @param serialno: the serial number of the device or emulator to connect to @type sample: boolean @param sample: whether take snapshot as an sampling ''' self.device = device self.sample = sample self.contactCounter = 0 self.startStatus = False '''the status which indicate whether the contacts activity is started''' #use below code to remove the status bar from the snapshot width = int(device.getProperty('display.width')) height = int(device.getProperty('display.height')) density = device.getProperty('display.density') if density == .75: statusBarHeight = 19 elif density == 1.5: statusBarHeight = 38 elif density == 2.0: statusBarHeight = 50 else: statusBarHeight = 25 self.snap_rect = 0, statusBarHeight, width, height - statusBarHeight #define the point coordinate used to slide screen self.left = (width / 4, height / 2) self.right = (width / 4 * 3, height / 2) self.up = (width / 2, height / 4) self.down = (width / 2, height / 4 * 3) self.center = (width / 2, height / 2) trace('before instance') self.vc = ViewClient(device, devID) trace('after instance') def start(self): ''' start the contacts activity and set the startStatus True if contacts is ready. ''' trace('Starting activity ...') self.device.startActivity(component=componentName) sleep(2) self.startStatus = self.goList() trace('Contacts is started, checking the contacts status...') self.isReady() sleep(2) def stop(self): ''' stop the contacts activity and set the startStatus False ''' self.device.shell('am force-stop %s' % package) trace('force stop contacts package %s' % package) self.startStatus = False def menu(self): ''' press menu ''' self.device.press('KEYCODE_MENU', 'DOWN_AND_UP') trace('press menu') def scroll(self, down=True, times=1): ''' scoll up or down for some times @type down: boolead @param down: scroll down if True or scroll up @type times: int @param times: how many times to scroll ''' keycode = 'KEYCODE_DPAD_DOWN' if down else 'KEYCODE_DPAD_UP' for i in range(times): self.device.press(keycode, 'DOWN_AND_UP') trace('scroll %s' % str) def back(self): ''' press back ''' self.device.press('KEYCODE_BACK', 'DOWN_AND_UP') trace('press back') def slide(self, str, view=None): ''' slide the screen @type: str @param: 'left','right','up','down' @type view: @param view: specify the view, default to None ''' if str not in ['left', 'right', 'up', 'down']: raise SyntaxError( "wrong parameter: choose from 'left','right','up' or 'down'") try: cX, cY = view.getCenter() width = view.getWidth() height = view.getHeight() cL = cX - width / 4, cY cR = cX + width / 4, cY cU = cX, cY - height / 4 cD = cX, cY + height / 4 except AttributeError: pass (left, right, up, down) = (cL, cR, cU, cD) if view else (self.left, self.right, self.up, self.down) nav = { 'left': { 'start': right, 'end': left }, 'right': { 'start': left, 'end': right }, 'up': { 'start': down, 'end': up }, 'down': { 'start': up, 'end': down } } self.device.drag(nav[str]['start'], nav[str]['end'], 0.1, 1) trace('slide the screen from %s to %s ' % (nav[str]['start'], nav[str]['end'])) sleep(2) def getView(self, str, cD=False, iD=False, dump=True, regex=False): ''' get the view with the specified text, content description or viewId @type str: str @param str: the query string @type cD: boolean @param cD: whether handle the query str as content description @type iD: boolean @param iD: whether handle the query str as viewId @type dump: boolean @param dump: whether execute dump before findView, depending on whether the screen is changed @return: the view found ''' if dump: trace('before dump') self.vc.dump() trace('after dump') if cD: view = self.vc.findViewWithContentDescription(str) trace('Query view with content description: %s, return is %s' % (str, view is not None)) return view elif iD: view = self.vc.findViewById(str) trace('Query view by id: %s, return is %s' % (str, view is not None)) return view elif regex: view = self.vc.findViewWithAttributeThatMatches( 'text', re.compile(str)) trace('Query view that match attribute: %s, return is %s' % (str, view is not None)) return view else: view = self.vc.findViewWithText(str) trace('Query view with text: %s, return is %s ' % (str, view is not None)) return view def isReady(self): ''' check whether the contacts is ready. @return: True ''' while True: view = self.getView( 'Contacts list is being updated to reflect the change of language.' ) if not view: trace('Contacts is ready') break else: trace('Contacts is not ready, please wait!') sleep(2) return True def isEmpty(self): ''' check whether the contacts is empty @return: True or False ''' self.check() view = self.getView('No contacts.') if view: trace('Contacts list is empty') return True else: trace('Contacts list is not empty') return False def getCounter(self): ''' get the contacts counter @return: the current contacts counter ''' self.goList() if self.isEmpty(): self.contactCounter = 0 else: while not self.getView('\d+ contacts?', regex=True): self.slide('down') sleep(3) self.contactCounter = int( self.getView('\d+ contacts?', regex=True, dump=False).getText().split()[0]) trace('current contacts counter is %d' % self.contactCounter) return self.contactCounter def goList(self): ''' check whether the screen is in contacts list view, if not, go list view via pressing back key @return: True ''' while True: view = self.getView("All contacts", cD=True) if not view: self.back() sleep(3) else: if not view.isSelected(): trace('Touch "All contacts"') view.touch() break trace('Goto contacts list view') return True def goEdit(self): ''' check whether the contacts is empty, then select adding and go to edit view. @return: True ''' self.check() try: self.getView('Add Contact', cD=True, dump=False).touch() trace('Touch "Add Contact"') sleep(5) return True except AttributeError: pass try: self.getView('Create a new contact', dump=False).touch() trace('Touch "Create a new contact"') sleep(5) self.getView('Keep local').touch() trace('Select "Keep local"') sleep(5) return True except AttributeError: pass def check(self): ''' check whether the contacts is started before other operation about contacts @return: True ''' if not self.startStatus: trace("Wrong code! please start contacts firstly in you code") raise SyntaxError('contacts should be start firstly!') return True def snapshot(self, title): ''' take snapshot @type title: str @param title: specify the title of snapshot @return: snapshot object ''' snapName = title + '.png' snapFolder = 'snapshot' os.system('if not exist %s\\%s mkdir %s\\%s' % (logPath, snapFolder, logPath, snapFolder)) snapFile = logPath + '\\' + snapFolder + '\\' + snapName result = self.device.takeSnapshot().getSubImage(self.snap_rect) trace('take snapshot without the statusbar') result.writeToFile(snapFile, 'png') trace('save the snapshot to file: %s ' % snapFile) return result def wipe(self, view): ''' wipe the text in specified view ''' try: self.device.drag(view.getXY(), view.getXY(), 1, 1) trace('wipe text: %s' % str(view.getText())) self.device.press('KEYCODE_DEL', 'DOWN_AND_UP') except: Exception('wipe failed') def addContact(self, name='', phone='', email='', address=''): self.goEdit() try: offset = 0 if name: view = self.getView('id/no_id/27', iD=True) trace('type %s' % name) view.type(name) view.touch() if phone: view = self.getView('id/no_id/46', iD=True, dump=False) trace('type %s' % phone) view.type(phone) offset += 4 sleep(2) if email: view = self.getView('id/no_id/' + str(57 + offset), iD=True) trace('type %s' % email) view.type(email) offset += 4 sleep(2) if address: view = self.getView('id/no_id/' + str(68 + offset), iD=True) trace('type %s' % address) view.type(address) sleep(2) view = self.getView('Done', dump=False) view.touch() trace('Touch Done') finally: sleep(5) self.goList() def goEditExistContact(self, str): try: self.search(str).touch() sleep(4) except AttributeError: trace('No contact with info ' + str + ' found') return False self.menu() sleep(1) self.scroll(1) self.device.press('KEYCODE_ENTER') sleep(3) return True def editCompany(self, company): view = self.getView('Add organization') if view: trace('Step: add a organization info') view.touch() sleep(1) trace('add the company info') self.device.type(company) sleep(1) else: trace('Step: Edit the organization info') view = self.getView('id/no_id/42', iD=True) self.wipe(view) trace('Edit the company info') self.device.type(company) sleep(1) def editDetails(self, contactsInfo, fieldName, content, update=True): ''' edit details of contact with add or update @type contactsInfo: str @param contactsInfo: information of contacts @type fieldName: str @param fieldName: field string of @return: snapshot object ''' self.goEditExistContact(contactsInfo) if fieldName not in [ 'Name', 'Phone', 'Email', 'Address', 'Company', 'Website', 'Nickname', 'Notes' ]: raise SyntaxError( "wrong 2nd parameter: fieldName choose from 'Name','Phone','Email','Address','Company','Website','Nickname','Notes'" ) if 'Name' == fieldName: self.editName(content) if 'Company' == fieldName: self.editCompany(content) addOrUpdate = 'update' if update else 'add' if 'update' == addOrUpdate: self.updateDetails(fieldName, content) if 'add' == addOrUpdate: self.addDetails(fieldName, content) self.getView('Done', dump=False).touch() trace('Click Done') sleep(3) self.goList() def editName(self, str): #find EditText of Name view = self.getView('id/no_id/27', iD=True) #edit name self.wipe(view) view.type(str) sleep(1) trace("edit contact's name OK") def addDetails(self, fieldName, content): trace('edit' + fieldName + 'with add') #touch 'Add another field' while not self.getView('Add another field').touch(): self.slide('up') sleep(2) sleep(3) #touch fieldName and edit while not self.getView(fieldName): view2 = self.getView('id/no_id/2', iD=True, dump=False) self.slide('up', view2) self.getView(fieldName, dump=False).touch() sleep(2) self.device.type(content) sleep(1) trace('edit' + fieldName + 'with add OK') def updateDetails(self, fieldName, content): trace('Edit field ' + fieldName + ' info') while not self.getView(fieldName): self.slide('up') sleep(2) view = self.getView(fieldName, dump=False) view2 = self.getView(view.getId()[:-2] + str(int(view.getId()[-2:]) + 6), iD=True) self.wipe(view2) sleep(1) view2.type(content) sleep(1) return True def search(self, str): ''' @type str: str @param str: specify the search keyword ##@return: the view of search result if search result is not null, else return None ''' trace("start searching...") self.goList() searchView = self.getView("Search", True) searchView.touch() sleep(2) self.device.type(str) trace("search keyword is: " + str) #the id of 1st search result is always 28 if self.getView("No contacts"): trace("No contact searched") return None else: return self.getView("id/no_id/28", iD=True) def sortAndViewAs(self, sortByFirstName=True, viewAsFirstNameFirst=True): ''' sort contact name @type sortByFirstName: boolean @param sortByFirstName: whether sort contact name by first name @type viewAsFirstNameFirst: boolean @param viewAsFirstNameFirst: whether view contact by first name first ''' self.goList() trace("start sorting...") self.device.press("KEYCODE_MENU", "DOWN_AND_UP") settingsView = self.getView("Settings") settingsView.touch() sleep(2) self.getView("Sort list by").touch() if sortByFirstName: self.getView("First name").touch() sleep(2) self.getView("View contact names as").touch() sleep(2) if viewAsFirstNameFirst: self.getView("First name first").touch() else: self.getView("Last name first").touch() else: self.getView("Last name").touch() sleep(2) self.getView("View contact names as").touch() sleep(2) if viewAsFirstNameFirst: self.getView("First name first").touch() else: self.getView("Last name first").touch() sleep(2) def favor(self, str, favor=True): ''' add or cancel contact to favorites @type str: str @param str: specify the search string @type favor: boolean @param favor: add if True ''' try: self.search(str).touch() sleep(3) except AttributeError: trace('no matched contact found, operation failed!') self.goList() return False aim, action = ('Add to favorites', 'add') if favor else ('Remove from favorites', 'remov') try: self.getView(aim, cD=True).touch() trace('%s successfully' % aim) except AttributeError: trace('%s has been %sed in favorites, not have to %s repeatedly' % (str, action, action)) sleep(3) self.goList() return True def delete(self, kwd=''): '''delete one contact @type kwd: string @param kwd: keyword which contact to be delete, if none,delete first contact @return: ''' #self.start() #trace('launch on contact application') self.goList() if self.isEmpty(): trace('Could not find any contact data,no record!') raise SyntaxError('Could not find any contact data,no record!') if not kwd: # keyword is empty,delete first contact trace('keyword is none, first contact with be delete') find = self.getView('id/no_id/27', iD=True, dump=False) #if find != None: else: # keyword is not none # search specifying contact by keyword find = self.search(kwd) trace('') # if find != None: if not find: trace('Could not find the contact : ' + kwd) raise SyntaxError('Could not find the contact : ' + kwd) else: # delete operate find.touch() sleep(3) trace('show contact detail information') sleep(1) self.device.press('KEYCODE_MENU') sleep(4) delete_menu = self.getView('Delete') trace('choose delete contact') delete_menu.touch() # confirm delete operate ok_menu = self.getView('OK') ok_menu.touch() sleep(3) # if current activity is not Main Activity back to Main Activity self.goList() if 0 == self.getCounter(): trace(' all contacts has been deleted, no record!') trace('operation success.')
def Call(): try: cdir=os.getcwd() adir=str(glob.glob(cdir + "/" + "logcat.txt")) cut=adir.split("/") before=cut[-1] global final final=before.replace("']", "") if final=="logcat.txt": print("Log file found Removing now.....") os.remove(final) else: print("No log file found...........") os.system("adb shell pm clear com.android.phone") time.sleep(10) check() time.sleep(1) os.system("adb shell cmd statusbar collapse") time.sleep(1) print("bye") if gets==str("4G Signal") or String==str("LTE Signal") or String==str("4G"): try: Call="adb shell am start -a android.intent.action.CALL -d tel:" + str(ISDN) output=subprocess.Popen(Call,stdout=subprocess.PIPE).communicate()[0] time.sleep(15) os.system("adb logcat -d time >> logcat.txt") time.sleep(4) file=open("logcat.txt", "r") lines= file.read() if "CallState DIALING -> ACTIVE" in lines and "isVolteCall()" in lines: time.sleep(1) os.system("adb shell screencap -p /sdcard/Automation/"+PLMN+"call.png") time.sleep(1) os .system("adb pull /sdcard/Automation/"+PLMN+"call.png "+fin+PLMN+"call.png" ) time.sleep(6) os.system("adb shell input keyevent KEYCODE_ENDCALL") sheet1.write(j,2,"PASS") file.close() elif "CallState DIALING -> DISCONNECTED" in lines: time.sleep(1) os.system("adb shell screencap -p /sdcard/Automation/"+PLMN+"call.png") time.sleep(1) os .system("adb pull /sdcard/Automation/"+PLMN+"call.png "+fin+PLMN+"call.png" ) time.sleep(2) sheet1.write(j,2,"FAIL") #############Write it in excel file.close() elif "CallState DIALING -> DIALING" in lines: time.sleep(3) os.system("adb shell screencap -p /sdcard/Automation/"+PLMN+"call.png") time.sleep(1) os .system("adb pull /sdcard/Automation/"+PLMN+"call.png "+fin+PLMN+"call.png" ) time.sleep(2) os.system("adb shell input keyevent KEYCODE_ENDCALL") sheet1.write(j,2,"FAIL")#############Write it in excel file.close() elif "CallState DIALING -> ACTIVE" in lines: time.sleep(5) os.system("adb shell screencap -p /sdcard/Automation/"+PLMN+"call.png") time.sleep(1) os .system("adb pull /sdcard/Automation/"+PLMN+"call.png "+fin+PLMN+"call.png" ) time.sleep(2) os.system("adb shell input keyevent KEYCODE_ENDCALL") sheet1.write(j,2,"FAIL") file.close() elif "CallState DIALING" not in lines: time.sleep(3) os.system("adb shell screencap -p /sdcard/Automation/"+PLMN+"call.png") time.sleep(1) os .system("adb pull /sdcard/Automation/"+PLMN+"call.png "+fin+PLMN+"call.png" ) time.sleep(2) os.system("adb shell input keyevent KEYCODE_ENDCALL") sheet1.write(j,0,PLMN) sheet1.write(j,2,"FAIL")#############Write it in excel file.close() except: print("Exception while dialing.......") else: sheet1.write(j,2,"FAIL") os.system("adb shell input keyevent KEYCODE_WAKEUP") time.sleep(1) os.system("adb shell pm clear com.android.contacts") time.sleep(1) os.system("adb shell input keyevent KEYCODE_HOME") from com.dtmilano.android.viewclient import ViewClient device, serialno=ViewClient.connectToDeviceOrExit() vc=ViewClient(device=device, serialno=serialno) try: vc.findViewWithContentDescription("Phone").touch() vc.dump() time.sleep(1) os.system("adb shell screencap -p /sdcard/Automation/"+PLMN+"callog.png") time.sleep(2) os .system("adb pull /sdcard/Automation/"+PLMN+"callog.png"+fin+PLMN+"callog.png") time.sleep(2) ###############TakeScreenshot os.system("adb shell input keyevent KEYCODE_HOME") except: print("Exception occured while finding element") except: print("An Exception occured......")
def SMS(): try: cdir=os.getcwd() adir=str(glob.glob(cdir + "/" + "logcat.txt")) cut=adir.split("/") before=cut[-1] global final final=before.replace("']", "") os.system("adb shell pm clear com.android.phone") time.sleep(10) check() os.system("adb shell cmd statusbar collapse") time.sleep(1) if gets==str("4G Signal") or String==str("LTE Signal") or String==str("4G"): if final=="logcat.txt": print("Log file found Removing now.....") os.remove(final) else: print("No log file found..........") try: time.sleep(1) os.system("adb shell pm clear com.google.android.apps.messaging") from com.dtmilano.android.viewclient import ViewClient device, serialno=ViewClient.connectToDeviceOrExit() vc=ViewClient(device=device, serialno=serialno) if vc.findViewWithContentDescription("Messages"): vc.findViewWithContentDescription("Messages").touch() time.sleep(1) vc.dump() else: device.startActivity("com.huawei.android.launcher/com.huawei.android.launcher.unihome.UniHomeLauncher") time.sleep(1) vc.dump() vc.findViewWithContentDescription("Start chat").touch() time.sleep(1) vc.dump() vc.findViewById("com.google.android.apps.messaging:id/recipient_text_view").touch() time.sleep(2) vc.dump() device.shell("input text " + str(ISDN)) vc.dump() time.sleep(3) vc.findViewById("com.google.android.apps.messaging:id/contact_picker_create_group").touch() time.sleep(1) vc.dump() vc.findViewById("com.google.android.apps.messaging:id/compose_message_text").setText("Hi") time.sleep(1) vc.dump() vc.findViewById("com.google.android.apps.messaging:id/send_message_button_container").touch() time.sleep(4) vc.dump() os.system("adb logcat -d time >> logcat.txt") time.sleep(6) file=open("logcat.txt", "r") lines= file.read() if "BugleDataMode: Processing changed messages for 357" in lines or "Done sending SMS message{id:357} conversation{id:50}, status: MANUAL_RETRY" in lines or "process from ProcessSentMessageAction due to sms_send failure with queues:" in lines: sheet1.write(j,3,"FAIL") time.sleep(1) os.system("adb shell screencap -p /sdcard/Automation/"+PLMN+"sms.png") time.sleep(1) os .system("adb pull /sdcard/Automation/"+PLMN+"sms.png "+fin+PLMN+"sms.png" ) time.sleep(1) file.close() elif "status: SUCCEEDED" in lines: sheet1.write(j,3,"PASS") time.sleep(1) os.system("adb shell screencap -p /sdcard/Automation/"+PLMN+"sms.png") time.sleep(1) os .system("adb pull /sdcard/Automation/"+PLMN+"sms.png "+fin+PLMN+"sms.png" ) time.sleep(1) file.close() #Take screenshot except: print("Exception while sending SMS..............") time.sleep(1) os.system("adb shell pm clear com.google.android.apps.messaging") time.sleep(1) else: sheet1.write(j,3,"FAIL") os.system("adb shell input keyevent KEYCODE_HOME") time.sleep(2) for i in range(4): from com.dtmilano.android.viewclient import ViewClient device, serialno=ViewClient.connectToDeviceOrExit() vc=ViewClient(device=device, serialno=serialno) if vc.findViewWithText("Settings"): vc.dump() vc.findViewWithText("Settings").touch() vc.dump() vc.findViewWithText("Wireless & networks").touch() vc.dump() vc.findViewWithText("Mobile network").touch() vc.dump() break else: os.system("adb shell input swipe 876 856 102 949 ") time.sleep(1) from com.dtmilano.android.viewclient import ViewClient device, serialno=ViewClient.connectToDeviceOrExit() vc=ViewClient(device=device, serialno=serialno) if vc.findViewWithText("Settings"): vc.dump() vc.findViewWithText("Settings").touch() vc.dump() vc.findViewWithText("Wireless & networks").touch() vc.dump() vc.findViewWithText("Mobile network").touch() vc.dump() break from com.dtmilano.android.viewclient import ViewClient device, serialno=ViewClient.connectToDeviceOrExit() vc=ViewClient(device=device, serialno=serialno) os.system("adb shell screencap -p /sdcard/Automation/"+PLMN+"Settings.png") time.sleep(1) os .system("adb pull /sdcard/Automation/"+PLMN+"Settings.png "+fin+PLMN+"Settings.png" ) time.sleep(1) except: print("An Exception occured......")
class contacts: ''' contacts class ''' def __init__(self, device, devID='emulator-5554',sample = False): ''' constructor @type device: MonkeyDevice @param device: The device or emulator connected @type devID: str @param serialno: the serial number of the device or emulator to connect to @type sample: boolean @param sample: whether take snapshot as an sampling ''' self.device=device self.sample=sample self.startStatus=False '''the status which indicate whether the contacts activity is started''' self.vc=ViewClient(device, devID) #use below code to remove the status bar from the snapshot width = int(device.getProperty('display.width')) height = int(device.getProperty('display.height')) density = device.getProperty('display.density') if density == .75: statusBarHeight = 19 elif density == 1.5: statusBarHeight = 38 elif density == 2.0: statusBarHeight = 50 else: statusBarHeight = 25 self.snap_rect = 0, statusBarHeight, width, height - statusBarHeight def start(self): ''' start the contacts activity and set the startStatus True if contacts is ready. ''' self.device.startActivity(component=componentName) sleep(3) self.startStatus = self.isReady() def back(self): ''' press back ''' self.device.press('KEYCODE_BACK','DOWN_AND_UP') def getView(self,str,cD=False,iD=False): ''' get the view with the specified text, content description or viewId @type str: str @param str: the query string @type cD: boolean @param cD: whether handle the query str as content description @type iD: boolean @param iD: whether handle the query str as viewId @return: the view found ''' self.vc.dump() sleep(3) if not cD: if not iD: return self.vc.findViewWithText(str) else: return self.vc.findViewById(str) else: return self.vc.findViewWithContentDescription(str) def isReady(self): ''' check whether the contacts is ready. ''' while True: view=self.getView('Contact list is being updated to reflect the change of language.') if not view: trace('Contacts is ready') break else: trace('Contacts is not ready, please wait!') sleep(2) return True def goEdit(self): ''' check whether the contact is empty, then select adding and go to edit view. @return: True ''' self.check() view=self.getView('Create a new contact') if view: view.touch() trace('Click "Create a new contact"') view=self.getView('Keep local') if view: view.touch() trace('Select "Keep local"') else: view=self.getView('Add Contact',True) view.touch() trace('Click "Add Contact"') return True def check(self): ''' check whether the contacts is started before other operation about contacts @return: True ''' if not self.status: trace("Wrong code! please start contacts firstly in you code") raise SyntaxError('contacts should be start firstly!') return True def snapshot(self,title): ''' take snapshot @type title: str @param title: specify the title of snapshot ''' snapName = title + '.png' snapFile = logPath + '\\' + snapName result = self.device.takeSnapshot().getSubImage(self.snap_rect) result.writeToFile(snapFile,'png') def addContact(self,name='',phone='',email=''): #notice firstly call self.goEdit() pass def editDetails(self,phone=''): pass def search(self,str): ''' @type str: str @param str: specify the search keyword ##@return: the view of search result if search result is not null, else return None ''' trace("start searching...") trace("check contact main UI, dump, please wait...") self.vc.dump() while not self.getView("Search",True): self.device.press('KEYCODE_BACK') sleep(2) self.vc.dump() searchView=self.getView("Search",True) searchView.touch() self.device.type(str) trace("search keyword is: "+str) self.snapshot("search_result") ''' tmp=[] self.vc.dump() trace("dump, please wait...") #the id of 1st search result is always 28 for i in self.vc.findViewsContainingPoint((100,200)): tmp.append(i.getId()) result=int(tmp[len(tmp)-1][-2:]) if(result<28): trace("search result: nothing") return None else: self.snapshot("search_result") return self.vc.findViewById(tmp[len(tmp)-1]) ''' def sortAs(self, sortByFirstName=True): ''' sort contact name @type sortByFirstName: boolean @param sortByFirstName: whether sort contact name by first name ''' trace("check contact main UI, dump, please wait...") self.vc.dump() while not self.getView("Search",True): self.device.press('KEYCODE_BACK') sleep(2) self.vc.dump() trace("start sorting...") self.device.press("KEYCODE_MENU","DOWN_AND_UP") trace("click menu, dump, please wait...") self.vc.dump() settingsView=self.getView("Settings") settingsView.touch() sleep(2) trace("click Settings, dump, please wait...") self.vc.dump() self.vc.findViewWithTextOrRaise("Sort list by").touch() trace("click Sort list by, dump, please wait...") self.vc.dump() if sortByFirstName: self.vc.findViewWithTextOrRaise("First name").touch() else: self.vc.findViewWithTextOrRaise("Last name").touch() sleep(2) #conflict with check at the begining #self.device.press("KEYCODE_BACK","DOWN_AND_UP") #sleep(2) def viewAs(self, viewAsFirstNameFirst=True): ''' view contact name @type viewAsFirstNameFirst: boolean @param viewAsFirstNameFirst: whether view contact by first name first ''' trace("check contact main UI, dump, please wait...") self.vc.dump() while not self.getView("Search",True): self.device.press('KEYCODE_BACK') sleep(2) self.vc.dump() trace("start viewing...") self.device.press("KEYCODE_MENU","DOWN_AND_UP") trace("click menu, dump, please wait...") self.vc.dump() settingsView=self.getView("Settings") settingsView.touch() sleep(2) trace("click Settings, dump, please wait...") self.vc.dump() self.vc.findViewWithTextOrRaise("View contact names as").touch() trace("click View contact names as, dump, please wait...") self.vc.dump() if viewAsFirstNameFirst: self.vc.findViewWithTextOrRaise("First name first").touch() else: self.vc.findViewWithTextOrRaise("Last name first").touch() sleep(2) #conflict with check at the begining #self.device.press("KEYCODE_BACK","DOWN_AND_UP") #sleep(2) def favorite(self,name=''): pass
class contacts: ''' contacts class ''' def __init__(self, device, devID='emulator-5554',sample = False): ''' constructor @type device: MonkeyDevice @param device: The device or emulator connected @type devID: str @param serialno: the serial number of the device or emulator to connect to @type sample: boolean @param sample: whether take snapshot as an sampling ''' self.device=device self.sample=sample self.startStatus=False '''the status which indicate whether the contacts activity is started''' self.vc=ViewClient(device, devID) #use below code to remove the status bar from the snapshot width = int(device.getProperty('display.width')) height = int(device.getProperty('display.height')) density = device.getProperty('display.density') if density == .75: statusBarHeight = 19 elif density == 1.5: statusBarHeight = 38 elif density == 2.0: statusBarHeight = 50 else: statusBarHeight = 25 self.snap_rect = 0, statusBarHeight, width, height - statusBarHeight def start(self): ''' start the contacts activity and set the startStatus True if contacts is ready. ''' self.device.startActivity(component=componentName) sleep(3) self.startStatus = self.isReady() def back(self): ''' press back ''' self.device.press('KEYCODE_BACK','DOWN_AND_UP') def getView(self,str,cD=False,iD=False): ''' get the view with the specified text, content description or viewId @type str: str @param str: the query string @type cD: boolean @param cD: whether handle the query str as content description @type iD: boolean @param iD: whether handle the query str as viewId @return: the view found ''' self.vc.dump() sleep(3) if not cD: if not iD: return self.vc.findViewWithText(str) else: return self.vc.findViewById(str) else: return self.vc.findViewWithContentDescription(str) def isReady(self): ''' check whether the contacts is ready. ''' while True: view=self.getView('Contact list is being updated to reflect the change of language.') if not view: trace('Contacts is ready') break else: trace('Contacts is not ready, please wait!') sleep(2) return True def goEdit(self): ''' check whether the contact is empty, then select adding and go to edit view. @return: True ''' self.check() view=self.getView('Create a new contact') if view: view.touch() trace('Click "Create a new contact"') view=self.getView('Keep local') if view: view.touch() trace('Select "Keep local"') else: view=self.getView('Add Contact',True) view.touch() trace('Click "Add Contact"') return True def check(self): ''' check whether the contacts is started before other operation about contacts @return: True ''' if not self.startStatus: trace("Wrong code! please start contacts firstly in you code") raise SyntaxError('contacts should be start firstly!') return True def snapshot(self,title): ''' take snapshot @type title: str @param title: specify the title of snapshot ''' snapName = title + '.png' snapFile = logPath + '\\' + snapName result = self.device.takeSnapshot().getSubImage(self.snap_rect) result.writeToFile(snapFile,'png') def addContact(self,name='',phone='',email=''): #notice firstly call self.goEdit() pass def editDetails(self,name='',phone='',email='',notes='',address='',nickname=''): ''' edit contact details ''' self.check() view = self.getView('id/no_id/27',iD=True) view.touch() sleep(4) trace('enter contact OK') self.device.press('KEYCODE_MENU','DOWN_AND_UP') view = self.getView('Edit') view.touch() sleep(3) trace('enter contact edit view OK') if not name=='': self.editName(name) if not phone=='': if self.getDetails('Phone'): self.editPhone(phone) else: self.editPhone(phone,add=True) self.back() sleep(3) self.back() def getDetails(self,getItem): if self.getView(getItem): return True else: self.device.drag((240,750),(240,50),5.0) sleep(1) if self.getView(getItem): return True else: return False def editName(self,name): trace("edit contact's name") self.check() #find EditText of Name view = self.getView('id/no_id/27',iD=True) #edit name self.device.drag(view.getXY(),view.getXY(),3.0) self.device.press('KEYCODE_DEL','DOWN_AND_UP') view.type(name) sleep(1) trace("edit contact's name OK") def editPhone(self,phone,add=False): trace("edit contact's phone") self.check() if not add: trace('edit phone with no add') #find EditText of Phone view = self.getView('Phone') editId = 'id/no_id/'+str(int((view.getId())[-2:])+6) view = self.getView(editId,iD=True) #edit phone number self.device.drag(view.getXY(),view.getXY(),3.0) self.device.press('KEYCODE_DEL','DOWN_AND_UP') view.type(phone) sleep(1) trace('edit phone with no add OK') else: trace('edit phone with add') #touch 'Add another field' view = self.getView('Add another field') view.touch() sleep(3) #touch 'Phone' and edit view = self.getView('Phone') view.touch() sleep(2) self.device.type(phone) sleep(1) trace('edit phone with add OK') def editEmail(self,email): pass def search(self,str): pass def sort(self): pass def favorite(self,name=''): pass
#select outlet skip if vc.findViewWithText('Select an Outlet'): vc.findViewWithContentDescriptionOrRaise(u'''Outlet''').touch() vc.sleep(_s) #screenshot of home screen device.takeSnapshot().save(path+'/whitelabel/WLA_database/'+appid+'/screenshots/1.png','PNG') vc.dump(window='-1') vc.sleep(_s) vc.dump(window='-1') #Theme 1 = STACK STACK if vc.findViewWithContentDescription(u'''stack_stack'''): id_scroll_view = vc.findViewByIdOrRaise("com.restwla.z"+appid+":id/scroll_view") #screenshot of information page vc.findViewByIdOrRaise('com.restwla.z'+appid+':id/home_option_information').touch() vc.sleep(_s) device.takeSnapshot().save(path+'/whitelabel/WLA_database/'+appid+'/screenshots/6.png','PNG') device.press('KEYCODE_BACK') #screenshot of photos page if vc.findViewById('com.restwla.z'+appid+':id/home_option_photos'): vc.findViewByIdOrRaise('com.restwla.z'+appid+':id/home_option_photos').touch() vc.sleep(_s) device.takeSnapshot().save(path+'/whitelabel/WLA_database/'+appid+'/screenshots/4.png','PNG') device.press('KEYCODE_BACK') #screenshot of Table Reservation
class action(object): def __init__(self,device,feature,devID='emulator-5554'): ''' constructor @type device: MonkeyDevice @param device: The device or emulator connected @type feature: str @param feature: feature name, use to mark in trace log @type devID: str @param serialno: the serial number of the device or emulator to connect to ''' self.device = device self.feature = feature #use below code to remove the status bar from the snapshot width = int(device.getProperty('display.width')) height = int(device.getProperty('display.height')) density = device.getProperty('display.density') if density == u'.75': statusBarHeight = 19 elif density == u'1.5': statusBarHeight = 38 elif density == u'2.0': statusBarHeight = 50 else: statusBarHeight = 25 self.snap_rect = 0, statusBarHeight, width, height - statusBarHeight #define the point coordinate used to slide screen self.left = (width/4, height/2) self.right = (width/4*3, height/2) self.up = (width/2, height/4) self.down = (width/2, height/4*3) self.center = (width/2, height/2) self.trace('Before instance') self.vc=ViewClient(device, devID) self.trace('After instance') def trace(self,str): ''' trace @type str: str @param str: specified trace info ''' mTrace('[%s]:%s'%(self.feature,str)) def sleep(self,duration=1): ''' Monkey sleep @type duration: int @param duration: how long to sleep ''' MonkeyRunner.sleep(duration) def menu(self): ''' press menu ''' self.device.press('KEYCODE_MENU','DOWN_AND_UP') self.trace('Press menu') self.sleep(3) def scroll(self,times=1,down=True): ''' scoll up or down for some times then touch the highlight submenu item @type down: boolead @param down: scroll down if True or scroll up @type times: int @param times: how many times to scroll ''' keycode = 'KEYCODE_DPAD_DOWN' if down else 'KEYCODE_DPAD_UP' for i in range(times): self.device.press(keycode,'DOWN_AND_UP') self.trace('Scroll %s' % keycode.split('_')[-1].lower()) self.device.press('KEYCODE_ENTER','DOWN_AND_UP') self.trace('Press Enter') self.sleep(2) def back(self): ''' press back ''' self.device.press('KEYCODE_BACK','DOWN_AND_UP') self.trace('Press back') def startComponent(self,componentName): ''' start activity @type componentName: str @param componentName: component name ''' self.device.startActivity(component=componentName) self.trace('Start component: %s' % componentName) self.sleep(2) def stopPackage(self,package): ''' stop activity @type package: str @param package: package name ''' self.device.shell('am force-stop %s' % package) self.trace('Force stop contacts package %s' % package) def type(self,str): ''' type @type str: str @param str: strings to type ''' self.device.type(str) self.trace('Type %s' % str) def slide(self,str,view=None): ''' slide the screen @type: str @param: 'left','right','up','down' @type view: view @param view: specify the view, default to None ''' if str not in ['left','right','up','down']: raise SyntaxError("Wrong Parameter: choose from 'left','right','up' or 'down'") try: cX = view.getX() cY = view.getY() width = view.getWidth() height = view.getHeight() cL = cX + width/4, cY + height/2 cR = cX + width/4*3, cY + height/2 cU = cX + width/2, cY + height/4 cD = cX + width/2, cY + height/4*3 except AttributeError: pass (left, right, up, down) = (cL, cR, cU, cD) if view else (self.left, self.right, self.up, self.down) nav = { 'left':{'start':right,'end':left}, 'right':{'start':left,'end':right}, 'up':{'start':down,'end':up}, 'down':{'start':up,'end':down} } self.device.drag(nav[str]['start'], nav[str]['end'], 0.1, 10) self.trace('Slide the screen from %s to %s ' % (nav[str]['start'],nav[str]['end'])) self.sleep(2) def getView(self,str,cD=False,iD=False,dump=True,regex=False): ''' get the view with the specified text, content description or viewId @type str: str @param str: the query string @type cD: boolean @param cD: whether handle the query str as content description @type iD: boolean @param iD: whether handle the query str as viewId @type dump: boolean @param dump: whether execute dump before findView, depending on whether the screen is changed @return: the view found ''' if dump: if DEBUG: self.trace('Before dump') self.vc.dump() if DEBUG: self.trace('After dump') if cD: view=self.vc.findViewWithContentDescription(str) self.trace('Query view with content description: %s, return is %s' % (str, view is not None)) return view elif iD: view=self.vc.findViewById(str) self.trace('Query view by id: %s, return is %s' % (str, view is not None)) return view elif regex: view=self.vc.findViewWithAttributeThatMatches('text',re.compile(str)) self.trace('Query view that match attribute: %s, return is %s' % (str, view is not None)) return view else: view=self.vc.findViewWithText(str) self.trace('Query view with text: %s, return is %s ' % (str, view is not None)) return view def touch(self,view): ''' touch the specified view @type view: view @param view: specified view @return: True ''' x = view.getX() y = view.getY() w = view.getWidth() h = view.getHeight() self.device.touch(x + w/2, y + h/2,'DWON_AND_UP') self.trace('Touch (%d,%d)' % (x + w/2, y + h/2)) self.sleep(3) return True def snapshot(self,title): ''' take snapshot @type title: str @param title: specify the title of snapshot @return: snapshot object ''' snapName = title + '_' + snapTime() + '.png' snapFolder = 'snapshot' os.system('if not exist %s\\%s mkdir %s\\%s' % (logPath, snapFolder, logPath, snapFolder)) snapFile = logPath + '\\' + snapFolder + '\\' + snapName result = self.device.takeSnapshot().getSubImage(self.snap_rect) self.trace('Take snapshot without the statusbar') result.writeToFile(snapFile,'png') self.trace('Save snapshot to file: %s ' % snapFile) return result def wipe(self,view): ''' wipe the text in specified view @type view: view @param view: specified view ''' try: self.device.drag(view.getXY(),view.getXY(),1,1) self.trace('Wipe text: %s' % str(view.getText())) self.device.press('KEYCODE_DEL','DOWN_AND_UP') except: Exception('Wipe failed')
class contacts: def __init__(self, device, devID='emulator-5554',sample = False): '''if sample is True, take snapshot as expected result.''' self.device=device self.sample=sample self.vc=ViewClient(device, devID) #use below code to remove the status bar from the snapshot width = int(device.getProperty('display.width')) height = int(device.getProperty('display.height')) density = device.getProperty('display.density') if density == .75: statusBarHeight = 19 elif density == 1.5: statusBarHeight = 38 elif density == 2.0: statusBarHeight = 50 else: statusBarHeight = 25 self.snap_rect = 0, statusBarHeight, width, height - statusBarHeight def start(self): self.device.startActivity(component=componentName) def getView(self,str,ContentDescription=False): self.vc.dump() if not contentDescription: return self.vc.getViewWithText(str) else: return self.vc.findViewWithContentDescription(str) def isReady(self): while True: view=self.getView('Contact list is being updated to reflect the change of language.') if not view: break sleep(2) return True def isEmpty(self): view=self.getView('Create a new contact') if view: view.touch() view=self.getView('Keep local') if view: view.touch() return True else: return True else: view=self.getView('Add Contact',True) view.touch() return True def snapshot(self,title): snapName = title + '.png' snapFile = logPath + '\\' + snapName result = self.device.takeSnapshot().getSubImage(self.snap_rect) result.writeToFile(snapFile,'png') def addContact(self): trace('start...') self.start() sleep(3) trace('take snapshot') self.snapshot('contact_snap') def editDetails(self): pass def search(self): pass def sort(self): pass def favorite(self): pass
class contacts: ''' contacts class ''' def __init__(self, device, devID='emulator-5554',sample = False): ''' constructor @type device: MonkeyDevice @param device: The device or emulator connected @type devID: str @param serialno: the serial number of the device or emulator to connect to @type sample: boolean @param sample: whether take snapshot as an sampling ''' self.device=device self.sample=sample self.contactCounter=0 self.startStatus=False '''the status which indicate whether the contacts activity is started''' #use below code to remove the status bar from the snapshot width = int(device.getProperty('display.width')) height = int(device.getProperty('display.height')) density = device.getProperty('display.density') if density == .75: statusBarHeight = 19 elif density == 1.5: statusBarHeight = 38 elif density == 2.0: statusBarHeight = 50 else: statusBarHeight = 25 self.snap_rect = 0, statusBarHeight, width, height - statusBarHeight #define the point coordinate used to slide screen self.left = (width/4, height/2) self.right = (width/4*3, height/2) self.up = (width/2, height/4) self.down = (width/2, height/4*3) self.center = (width/2, height/2) trace('before instance') self.vc=ViewClient(device, devID) trace('after instance') def start(self): ''' start the contacts activity and set the startStatus True if contacts is ready. ''' trace('Starting activity ...') self.device.startActivity(component=componentName) sleep(2) self.startStatus = self.goList() trace('Contacts is started, checking the contacts status...') self.isReady() sleep(2) def stop(self): ''' stop the contacts activity and set the startStatus False ''' self.device.shell('am force-stop %s' % package) trace('force stop contacts package %s' % package) self.startStatus = False def menu(self): ''' press menu ''' self.device.press('KEYCODE_MENU','DOWN_AND_UP') trace('press menu') def scroll(self,down=True,times=1): ''' scoll up or down for some times then touch the highlight submenu item @type down: boolead @param down: scroll down if True or scroll up @type times: int @param times: how many times to scroll ''' keycode = 'KEYCODE_DPAD_DOWN' if down else 'KEYCODE_DPAD_UP' for i in range(times): self.device.press(keycode,'DOWN_AND_UP') trace('scroll %s' % keycode.split('_')[-1].lower()) self.device.press('KEYCODE_ENTER','DOWN_AND_UP') trace('press Enter') def back(self): ''' press back ''' self.device.press('KEYCODE_BACK','DOWN_AND_UP') trace('press back') def slide(self,str,view=None): ''' slide the screen @type: str @param: 'left','right','up','down' @type view: @param view: specify the view, default to None ''' if str not in ['left','right','up','down']: raise SyntaxError("wrong parameter: choose from 'left','right','up' or 'down'") try: cX,cY = view.getCenter() width = view.getWidth() height = view.getHeight() cL = cX - width/4, cY cR = cX + width/4, cY cU = cX, cY - height/4 cD = cX, cY + height/4 except AttributeError: pass (left, right, up, down) = (cL, cR, cU, cD) if view else (self.left, self.right, self.up, self.down) nav = { 'left':{'start':right,'end':left}, 'right':{'start':left,'end':right}, 'up':{'start':down,'end':up}, 'down':{'start':up,'end':down} } self.device.drag(nav[str]['start'], nav[str]['end'], 0.1, 10) trace('slide the screen from %s to %s ' % (nav[str]['start'],nav[str]['end'])) sleep(2) def getView(self,str,cD=False,iD=False,dump=True,regex=False): ''' get the view with the specified text, content description or viewId @type str: str @param str: the query string @type cD: boolean @param cD: whether handle the query str as content description @type iD: boolean @param iD: whether handle the query str as viewId @type dump: boolean @param dump: whether execute dump before findView, depending on whether the screen is changed @return: the view found ''' if dump: trace('before dump') self.vc.dump() trace('after dump') if cD: view=self.vc.findViewWithContentDescription(str) trace('Query view with content description: %s, return is %s' % (str, view is not None)) return view elif iD: view=self.vc.findViewById(str) trace('Query view by id: %s, return is %s' % (str, view is not None)) return view elif regex: view=self.vc.findViewWithAttributeThatMatches('text',re.compile(str)) trace('Query view that match attribute: %s, return is %s' % (str, view is not None)) return view else: view=self.vc.findViewWithText(str) trace('Query view with text: %s, return is %s ' % (str, view is not None)) return view def isReady(self): ''' check whether the contacts is ready. @return: True ''' while True: view=self.getView('Contacts list is being updated to reflect the change of language.') if not view: trace('Contacts is ready') break else: trace('Contacts is not ready, please wait!') sleep(2) return True def isEmpty(self): ''' check whether the contacts is empty @return: True or False ''' self.check() view=self.getView('No contacts.') if view: trace('Contacts list is empty') return True else: trace('Contacts list is not empty') return False def getCounter(self): ''' get the contacts counter @return: the current contacts counter ''' self.goList() if self.isEmpty(): self.contactCounter=0 else: while True: try: self.contactCounter = int(self.getView('\d+ contacts?',regex=True).getText().split()[0]) break except AttributeError: self.slide('down') sleep(1) trace('current contacts counter is %d' % self.contactCounter) return self.contactCounter def goList(self): ''' check whether the screen is in contacts list view, if not, go list view via pressing back key @return: True ''' while True: view=self.getView("All contacts",cD=True) if not view: self.back() sleep(3) else: if not view.isSelected(): trace('Touch "All contacts"') view.touch() break trace('Goto contacts list view') return True def goEdit(self): ''' check whether the contacts is empty, then select adding and go to edit view. @return: True ''' self.check() try: self.getView('Add Contact',cD=True,dump=False).touch() trace('Touch "Add Contact"') sleep(5) return True except AttributeError: pass try: self.getView('Create a new contact',dump=False).touch() trace('Touch "Create a new contact"') sleep(5) self.getView('Keep local').touch() trace('Select "Keep local"') sleep(5) return True except AttributeError: pass def check(self): ''' check whether the contacts is started before other operation about contacts @return: True ''' if not self.startStatus: trace("Wrong code! please start contacts firstly in you code") raise SyntaxError('contacts should be start firstly!') return True def snapshot(self,title): ''' take snapshot @type title: str @param title: specify the title of snapshot @return: snapshot object ''' snapName = title + '.png' snapFolder = 'snapshot' os.system('if not exist %s\\%s mkdir %s\\%s' % (logPath, snapFolder, logPath, snapFolder)) snapFile = logPath + '\\' + snapFolder + '\\' + snapName result = self.device.takeSnapshot().getSubImage(self.snap_rect) trace('take snapshot without the statusbar') result.writeToFile(snapFile,'png') trace('save the snapshot to file: %s ' % snapFile) return result def wipe(self,view): ''' wipe the text in specified view ''' try: self.device.drag(view.getXY(),view.getXY(),1,1) trace('wipe text: %s' % str(view.getText())) self.device.press('KEYCODE_DEL','DOWN_AND_UP') except: Exception('wipe failed') def addContact(self,name='',phone='',email='',address=''): self.goEdit() try: offset = 0 if name: view=self.getView('id/no_id/27',iD=True) trace('type %s' % name) view.type(name) view.touch() if phone: view=self.getView('id/no_id/46',iD=True,dump=False) trace('type %s' % phone) view.type(phone) offset += 4 sleep(2) if email: view=self.getView('id/no_id/' + str(57 + offset), iD=True) trace('type %s' % email) view.type(email) offset += 4 sleep(2) if address: view=self.getView('id/no_id/' + str(68 + offset), iD=True) trace('type %s' % address) view.type(address) sleep(2) view=self.getView('Done',dump=False) view.touch() trace('Touch Done') finally: sleep(5) self.goList() def goEditExistContact(self,searchInfo): ''' go to Edit view of exist contact @type searchInfo: str @param searchInfo: information of contacts @return:True ''' trace('Search a contact to edit') view=self.search(searchInfo) if not view: raise SyntaxError('No '+searchInfo+' contact to edit') view.touch() sleep(4) self.device.press('KEYCODE_MENU') sleep(2) self.device.press('KEYCODE_DPAD_DOWN') sleep(1) self.device.press('KEYCODE_ENTER') sleep(4) return True def editName(self,name): ''' edit Name details of contacts @type name: str @param name: content of Name @return: True ''' #find EditText of Name view = self.getView('id/no_id/27',iD=True) #edit name self.wipe(view) view.type(name) sleep(1) trace("edit contact's name OK") return True def editCompany(self,company): ''' edit Company details of contacts @type company: str @param company: content of Company @return: True ''' view=self.getView('Add organization') if view: trace('Step: add a organization info') view.touch() sleep(1) trace('add the company info') self.device.type(company) sleep(1) else: trace('Step: Edit the organization info') view=self.getView('id/no_id/42',iD=True) self.wipe(view) trace('Edit the company info') self.device.type(company) sleep(1) return True def editDetails(self,contactsInfo,action='update',**editInfo): ''' edit details of contact with add or update @type contactsInfo: str @param contactsInfo: information of contacts @type action: str @param action: 'add' or 'update' details @type editInfo: str @param editInfo: collect all need edit information @return: True ''' self.goEditExistContact(contactsInfo) for fieldName in editInfo: if fieldName not in ['Name','Phone','Email','Address','Company','Website','Nickname','Notes']: raise SyntaxError("wrong parameter: fieldName choose from 'Name','Phone','Email','Address','Company','Website','Nickname','Notes'") if 'update'==action: for updateField in editInfo: if 'Name' == updateField: self.editName(editInfo[updateField]) elif 'Company' == updateField: self.editCompany(editInfo[updateField]) else: self.updateDetails(updateField,editInfo[updateField]) if 'add'==action: for addField in editInfo: if 'Name' == addField: self.editName(editInfo[addField]) elif 'Company' == addField: self.editCompany(editInfo[addField]) else: self.addDetails(addField,editInfo[addField]) self.getView('Done').touch() trace('Click Done') sleep(3) self.goList() return True def addDetails(self,fieldName,content): ''' add details of 'fieldName' with 'content' @type fieldName: str @param fieldName: name of field that will be eidt , e.g: Phone,Email,etc @type content: str @param content: edit content @return:True ''' trace('edit '+fieldName+ ' with add') #touch 'Add another field' while True: try: self.getView('Add another field').touch() sleep(3) break except AttributeError: self.slide('up') sleep(2) #touch fieldName and edit while True: try: self.getView(fieldName).touch() sleep(2) break except AttributeError: view2 = self.getView('id/no_id/2',iD=True,dump=False) self.slide('up',view2) sleep(1) self.device.type(content) sleep(1) trace('edit '+fieldName+' with add OK') return True def updateDetails(self,fieldName,content): ''' update details of 'fieldName' with 'content' @type fieldName: str @param fieldName: name of field that will be eidt , e.g: Phone,Email,etc @type content: str @param content: edit content @return:True ''' trace('Edit field '+fieldName+' info') #find fieldName while not self.getView(fieldName): self.slide('up') sleep(2) #get editView of fieldName view = self.getView(fieldName,dump=False) view2=self.getView(view.getId()[:-2]+str(int(view.getId()[-2:])+6),iD=True) #wipe old content and update with new content self.wipe(view2) sleep(1) view2.type(content) sleep(1) return True def search(self,str): ''' search contact by keyword @type str: str @param str: specify the search keyword @return: the view of search result if search result is not null, else return False ''' trace("start searching...") try: self.getView("Search",True).touch() sleep(2) self.device.type(str) trace("search keyword is: "+str) except AttributeError: if self.isEmpty(): trace("No contacts exist") else: trace("No contacts searched") return False #the id of 1st search result is always 28 return self.getView("id/no_id/28",iD=True) def sortAndViewAs(self, sort=True, first=True): ''' sort and view contact name @type sort: boolean @param sort: whether sort contact name or view contact @type first: boolean @param first: whether sort and view contact by first name or last name @return: boolean ''' trace("start sorting...") self.menu() self.scroll(times=4) sleep(2) sortOrView="Sort list by" if sort else "View contact names as" firstOrLast="First name*" if first else "Last name*" try: self.getView(sortOrView).touch() sleep(1) self.getView(firstOrLast,regex=True).touch() return True except AttributeError: return False finally: self.goList() def favor(self,str,favor=True): ''' add or cancel contact to favorites @type str: str @param str: specify the search string @type favor: boolean @param favor: add if True ''' try: self.search(str).touch() sleep(3) except AttributeError: trace('no matched contact found, operation failed!') self.goList() return False aim, action = ('Add to favorites', 'add') if favor else ('Remove from favorites', 'remov') try: self.getView(aim, cD=True).touch() trace('%s successfully' % aim) except AttributeError: trace('%s has been %sed in favorites, not have to %s repeatedly' % (str, action, action)) sleep(3) self.goList() return True def delete(self,kwd = ''): '''delete one contact @type kwd: string @param kwd: keyword which contact to be delete, if none,delete first contact @return: True if operate sucess, False if operate fail. ''' if self.isEmpty(): trace('Could not find any contact data,no record!') return False find = self.search(kwd) if kwd else self.getView('id/no_id/27',iD=True,dump=False) try: # delete operate find.touch() sleep(4) trace('show contact detail information') self.menu() sleep(3) self.scroll(times=3) trace('choose delete contact') self.getView('OK').touch() sleep(3) return True except AttributeError: return False finally: self.goList()
from com.dtmilano.android.viewclient import ViewClient USE_BROWSER = True # Starting: Intent { act=android.intent.action.MAIN flg=0x10000000 cmp=com.android.browser/.BrowserActivity } if USE_BROWSER: package = 'com.android.browser' activity = '.BrowserActivity' else: package = 'com.android.chrome' activity = 'com.google.android.apps.chrome.Main' component = package + "/" + activity uri = 'http://dtmilano.blogspot.com' device, serialno = ViewClient.connectToDeviceOrExit() device.startActivity(component=component, uri=uri) ViewClient.sleep(5) vc = ViewClient(device, serialno) if vc.getSdkVersion() >= 16: if USE_BROWSER: url = vc.findViewByIdOrRaise("id/no_id/12").getText() else: url = vc.findViewWithContentDescription("Search or type url").getText() else: url = vc.findViewByIdOrRaise("id/url").getText() if string.find(uri, url) != -1: print "%s successfully loaded" % uri else: print "%s was not loaded, url=%s" % (uri, url)
class contacts: ''' contacts class ''' def __init__(self, device, devID='emulator-5554', sample=False): ''' constructor @type device: MonkeyDevice @param device: The device or emulator connected @type devID: str @param serialno: the serial number of the device or emulator to connect to @type sample: boolean @param sample: whether take snapshot as an sampling ''' self.device = device self.sample = sample self.startStatus = False '''the status which indicate whether the contacts activity is started''' self.vc = ViewClient(device, devID) #use below code to remove the status bar from the snapshot width = int(device.getProperty('display.width')) height = int(device.getProperty('display.height')) density = device.getProperty('display.density') if density == .75: statusBarHeight = 19 elif density == 1.5: statusBarHeight = 38 elif density == 2.0: statusBarHeight = 50 else: statusBarHeight = 25 self.snap_rect = 0, statusBarHeight, width, height - statusBarHeight def start(self): ''' start the contacts activity and set the startStatus True if contacts is ready. ''' self.device.startActivity(component=componentName) sleep(3) self.startStatus = self.isReady() def back(self): ''' press back ''' self.device.press('KEYCODE_BACK', 'DOWN_AND_UP') def getView(self, str, cD=False, iD=False): ''' get the view with the specified text, content description or viewId @type str: str @param str: the query string @type cD: boolean @param cD: whether handle the query str as content description @type iD: boolean @param iD: whether handle the query str as viewId @return: the view found ''' self.vc.dump() sleep(3) if not cD: if not iD: return self.vc.findViewWithText(str) else: return self.vc.findViewById(str) else: return self.vc.findViewWithContentDescription(str) def isReady(self): ''' check whether the contacts is ready. ''' while True: view = self.getView( 'Contact list is being updated to reflect the change of language.' ) if not view: trace('Contacts is ready') break else: trace('Contacts is not ready, please wait!') sleep(2) return True def goEdit(self): ''' check whether the contact is empty, then select adding and go to edit view. @return: True ''' self.check() view = self.getView('Create a new contact') if view: view.touch() trace('Click "Create a new contact"') view = self.getView('Keep local') if view: view.touch() trace('Select "Keep local"') else: view = self.getView('Add Contact', True) view.touch() trace('Click "Add Contact"') return True def check(self): ''' check whether the contacts is started before other operation about contacts @return: True ''' if not self.startStatus: trace("Wrong code! please start contacts firstly in you code") raise SyntaxError('contacts should be start firstly!') return True def snapshot(self, title): ''' take snapshot @type title: str @param title: specify the title of snapshot ''' snapName = title + '.png' snapFile = logPath + '\\' + snapName result = self.device.takeSnapshot().getSubImage(self.snap_rect) result.writeToFile(snapFile, 'png') def addContact(self, name='', phone='', email=''): #notice firstly call self.goEdit() pass def editDetails(self, name='', phone='', email='', notes='', address='', nickname=''): ''' edit contact details ''' self.check() view = self.getView('id/no_id/27', iD=True) view.touch() sleep(4) trace('enter contact OK') self.device.press('KEYCODE_MENU', 'DOWN_AND_UP') view = self.getView('Edit') view.touch() sleep(3) trace('enter contact edit view OK') if not name == '': self.editName(name) if not phone == '': if self.getDetails('Phone'): self.editPhone(phone) else: self.editPhone(phone, add=True) self.back() sleep(3) self.back() def getDetails(self, getItem): if self.getView(getItem): return True else: self.device.drag((240, 750), (240, 50), 5.0) sleep(1) if self.getView(getItem): return True else: return False def editName(self, name): trace("edit contact's name") self.check() #find EditText of Name view = self.getView('id/no_id/27', iD=True) #edit name self.device.drag(view.getXY(), view.getXY(), 3.0) self.device.press('KEYCODE_DEL', 'DOWN_AND_UP') view.type(name) sleep(1) trace("edit contact's name OK") def editPhone(self, phone, add=False): trace("edit contact's phone") self.check() if not add: trace('edit phone with no add') #find EditText of Phone view = self.getView('Phone') editId = 'id/no_id/' + str(int((view.getId())[-2:]) + 6) view = self.getView(editId, iD=True) #edit phone number self.device.drag(view.getXY(), view.getXY(), 3.0) self.device.press('KEYCODE_DEL', 'DOWN_AND_UP') view.type(phone) sleep(1) trace('edit phone with no add OK') else: trace('edit phone with add') #touch 'Add another field' view = self.getView('Add another field') view.touch() sleep(3) #touch 'Phone' and edit view = self.getView('Phone') view.touch() sleep(2) self.device.type(phone) sleep(1) trace('edit phone with add OK') def editEmail(self, email): pass def search(self, str): pass def sort(self): pass def favorite(self, name=''): pass