def test_send_many_notifications(self): self.assertIsNotNone(os.getenv('DISPLAY')) notifications=api.import_notification_api() self.assertTrue(notifications) num_popups=15 # send a notification popup to the desktop one after the next for i in range(0, num_popups): notifications.display_generic_notification('test_send_many_notifications {}'.format(i), 'sample test line') time.sleep(1) # click on each stacked notification one by one for i in range(0, num_popups): self.assertEqual(self._get_notification_count(), 1) # FIXME: coordinates will not work unless 1980x1080 rawinput.click(715, 650) time.sleep(1) time.sleep(5) os.system('scrot /tmp/tests_screenshots/many_notifications_complete.png') # make sure all notifications popups are gone self.assertEqual(self._get_notification_count(), 0, msg='Notifications popups still found')
def out_mouse_click(pos, mode): """Click in current position """ if mode == "current": return rawinput.click(*read_mouse_pos()) elif mode == "abs": return rawinput.click(*pos) # Click in the game using game-relative coordinates. elif mode == "rel": if game_pos == 0: raise Exeption("Error: game_pos undefined.") return False # Bounds checking. if game_pos[0][0] <= pos[0] <= game_pos[1][0] and game_pos[0][1] <= pos[1] <= game_pos[1][1]: return rawinput.click(game_pos[0][0] + pos[0], game_pos[0][1] + pos[1]) else: raise Exeption("Error: position out of bounds.") return False elif mode == "ratio": if game_pos == 0: raise Exeption("Error: game_pos undefined.") return False # Bounds checking. if 0 <= pos[0] <= 1 and 0 <= pos[1] <= 1: return rawinput.click( game_pos[0][0] + pos[0] * (game_pos[1][0] - game_pos[0][0]), game_pos[0][1] + pos[1] * (game_pos[1][1] - game_pos[0][1]), ) else: raise Exeption("Error: position out of bounds.") return False raise Exeption("Error: incorrect mode.") return False
def test_check_coordinates_builtin(self): with self.assertRaises(ValueError): absoluteMotion(-5, 5) with self.assertRaises(ValueError): absoluteMotion(5, -5) with self.assertRaises(ValueError): absoluteMotionWithTrajectory(10, 10, -5, 5) with self.assertRaises(ValueError): absoluteMotionWithTrajectory(10, 10, 5, -5) with self.assertRaises(ValueError): absoluteMotionWithTrajectory(-5, 5, 10, 10) with self.assertRaises(ValueError): absoluteMotionWithTrajectory(5, -5, 10, 10) with self.assertRaises(ValueError): click(-5, 5) with self.assertRaises(ValueError): click(5, -5) with self.assertRaises(ValueError): doubleClick(-5, 5) with self.assertRaises(ValueError): doubleClick(5, -5) with self.assertRaises(ValueError): press(-5, 5) with self.assertRaises(ValueError): press(5, -5) with self.assertRaises(ValueError): release(-5, 5) with self.assertRaises(ValueError): release(5, -5)
def testOpenFileManager(self): launcher = self.ddedockobject.child("Launcher") launcher.point() filemanager = self.ddedockobject.child(self.filemanager) filemanager.click() rawinput.click(int(utils.resolution.width / 2), int(utils.resolution.height / 2)) time.sleep(2) win = utils.findWindow(self.filemanager_windowname) self.assertTrue(win != None)
def clickFocus(frame, maximize=False): """ Will focus on the window by clicking in the middle of its frame's titlebar. Input a frame or dialog, will try to get its coords and click the titlebar""" try: coordinates = (frame.position[0]+frame.size[0]/2, frame.position[1]+5) if maximize is False: click(coordinates[0], coordinates[1]) else: # a doubleClick to maximize as well doubleClick(coordinates[0], coordinates[1]) except: print("Warning: Could not clickFocus() at the app frame") return False
def change_calendar_month_to(context, month, year): # Show the context menu with year and a month panel = context.app.instance.child('Month Calendar') prev_year = panel.child('Previous year').position next_year = panel.child('Next year').position pos_diff = next_year[0] - prev_year[0] click_pos = prev_year[0] + int(pos_diff / 2) click(click_pos, next_year[1], button=3) # Select the date if pyatspi.STATE_FOCUSED not in context.app.instance.menu(year).getState().getStates(): context.app.instance.menu(year).click() context.app.instance.menu(year).menuItem(month).click()
def startViaKDEMenu(context, app): """ Will run the app through the standard application launcher """ corner_distance = 10 height = Gdk.Display.get_default().get_default_screen().get_root_window().get_height() click(corner_distance, height - corner_distance) plasma = root.application('plasma-desktop') plasma.child(name='Search:', roleName='label').parent.child(roleName='text').text = context.app.appCommand sleep(0.5) pressKey('enter') assert wait_until(lambda x: isKDEAppRunning(x), context.app, timeout=30),\ "Application failed to start" context.app.instance = root.application(context.app.a11yAppName)
def clickFocus(self, maximize=None): """ Will focus on the app by clicking in the middle of its window titlebar""" try: main_win = self.app.child(roleName='window', recursive=False) coordinates = (main_win.position[0]+main_win.size[0]/2, main_win.position[1]-10) if maximize is None: click(coordinates[0],coordinates[1]) else: #a doubleClick to maximize as well doubleClick(coordinates[0],coordinates[1]) except: printException() return False
def testCloseDeepinScreenshot(self): time.sleep(1) rawinput.click(int(utils.resolution.width / 2), int(utils.resolution.height / 2), 3) time.sleep(1) rawinput.click(int(utils.resolution.width / 4), int(utils.resolution.height / 4)) time.sleep(1) (status, output) = rt( "ps -ef | grep /usr/bin/deepin-screenshot | grep -v grep | awk '{print $9}'" ) time.sleep(4) self.assertTrue('' == output, "output is %s" % output)
def click(self, button=1): """ Generates a raw mouse click event, using the specified button. - 1 is left, - 2 is middle, - 3 is right. """ logger.log("Clicking on %s" % self.getLogString()) clickX = self.position[0] + self.size[0] / 2 clickY = self.position[1] + self.size[1] / 2 if config.debugSearching: logger.log("raw click on %s %s at (%s,%s)" % (self.name, self.getLogString(), str(clickX), str(clickY))) rawinput.click(clickX, clickY, button)
def configure_openpgp_account(tb): keyid = get_key_fpr() export_pub_key() open_account_setup(tb) settings = tb.findChild( orPredicate( GenericPredicate(name='Account Settings.*', roleName='frame'), GenericPredicate(name='Account Settings', roleName='dialog'), )) # assume only one account... settings.childNamed('End-To-End Encryption').doActionNamed('activate') settings.childNamed('Add Key.*').doActionNamed('press') settings.childNamed('Use your external key.*').doActionNamed('select') settings.childNamed('Continue').doActionNamed('press') settings.findChild(TBEntry('123456789.*')).text = keyid settings.button('Save key ID').doActionNamed('press') settings.findChild( GenericPredicate(name='0x%s.*' % keyid, roleName='radio button')).doActionNamed('select') settings.childNamed('OpenPGP Key Manager.*').doActionNamed('press') key_manager = tb.findChild( GenericPredicate(name='OpenPGP Key Manager', roleName='frame')) key_manager.findChild(GenericPredicate( name='File', roleName='menu')).doActionNamed('click') key_manager.findChild( GenericPredicate(name='Import Public Key(s) From File', roleName='menu item')).doActionNamed('click') file_chooser = tb.findChild( GenericPredicate(name='Import OpenPGP Key File', roleName='file chooser')) click(*file_chooser.childNamed('Home').position) click(*file_chooser.childNamed('pub.asc').position) file_chooser.childNamed('Open').doActionNamed('click') accept_dialog = tb.findChild( orPredicate( GenericPredicate(name='.*(%s).*' % keyid), GenericPredicate(name='.[0-9A-F]*%s' % keyid), )).parent accept_dialog.childNamed('OK').doActionNamed('press') tb.childNamed('Success! Keys imported.*').childNamed('OK').doActionNamed( 'press') doubleClick(*key_manager.findChild( GenericPredicate(name='Qubes test <user@localhost>.*')).position) key_property = tb.findChild( GenericPredicate(name="Key Properties.*", roleName='frame')) key_property.findChild( GenericPredicate(name="Yes, I've verified in person.*", roleName='radio button')).doActionNamed('select') key_property.childNamed('OK').doActionNamed('press') key_manager.findChild(GenericPredicate( name='Close', roleName='menu item')).doActionNamed('click')
def startViaKDEMenu(context, app): """ Will run the app through the standard application launcher """ corner_distance = 10 height = Gdk.Display.get_default().get_default_screen().get_root_window( ).get_height() click(corner_distance, height - corner_distance) plasma = root.application('plasma-desktop') plasma.child(name='Search:', roleName='label').parent.child( roleName='text').text = context.app.appCommand sleep(0.5) pressKey('enter') assert wait_until(lambda x: isKDEAppRunning(x), context.app, timeout=30),\ "Application failed to start" context.app.instance = root.application(context.app.a11yAppName)
def testOpenFileManager(self): google = self.ddedockobject.child(self.filemanager) google.click() rawinput.click(int(utils.resolution.width/2), int(utils.resolution.height/2)) if utils.dock.hidemode_keephidden != self.defaulthidemode: utils.setDdeDockHideMode(utils.dock.hidemode_keephidden) hidemode = utils.getDdeDockHideMode() hidestate = utils.getDdeDockHideState() self.assertTrue(hidemode == utils.dock.hidemode_keephidden) self.assertTrue(hidestate == utils.dock.hidestate_hide) win = utils.findWindow(self.filemanager_windowname) self.assertTrue(win != None)
def click(self, button=1): """ Generates a raw mouse click event, using the specified button. - 1 is left, - 2 is middle, - 3 is right. """ logger.log(str("Clicking on %s") % self.getLogString()) clickX = self.position[0] + self.size[0] / 2 clickY = self.position[1] + self.size[1] / 2 if config.debugSearching: logger.log(str("raw click on %s %s at (%s,%s)") % (str(self.name), self.getLogString(), str(clickX), str(clickY))) rawinput.click(clickX, clickY, button)
def push_front(self): logger.info("Push app front.") if self.is_fullscreen(): logger.info("Display is fullscreen.") _, _, w, h = self.dsp.extents rawinput.absoluteMotion(w/2, 0) rawinput.click(w/2+1, 0) self.drawing_area.grabFocus() # It makes me crazy. It says it always is un-focused when it runs in # auto-mode. But, it is focused when I run it manually. #is_focused(self.drawing_area) if not self.is_fullscreen(): logger.info("Display is window.") n = self.dsp.child(roleName="menu bar") do_click(n) logger.info("Push app front: success.")
def startViaMenu(self): """ Will run the app through the standard application launcher """ try: sleep(self.splashscreen_delay) # time before kwin starts up and the splash screen disappears height = Gdk.Display.get_default().get_default_screen().get_root_window().get_height() click(self.corner_distance,height - self.corner_distance) plasma = root.application('plasma-desktop') plasma.child(name='Search:', roleName='label').click() typeText(self.command) sleep(1) pressKey('enter') sleep(5) except: printException() return False self.__PID = self.getHighestPid() return self.checkRunning('Running %s via menu search' % self.appname)
def test_send_one_notification(self): self.assertIsNotNone(os.getenv('DISPLAY')) notifications=api.import_notification_api() self.assertTrue(notifications) # send a notification popup to the desktop notifications.display_generic_notification('test_send_one_notification', 'sample test line') time.sleep(1) # make sure there is a notification window self.assertEqual(self._get_notification_count(), 1, msg='Notification does not seem to popup') # FIXME: coordinates will not work unless 1980x1080 display rawinput.click(680, 650) time.sleep(5) os.system('scrot /tmp/tests_screenshots/one_notification_complete.png') # FIXME: for some reason the daemon always shows a notification "please remember to register" self.assertEqual(self._get_notification_count(), 0, msg='Notification does not disappear')
def do_click(node): is_showing(node) if node.roleName == 'menu' \ or node.roleName == 'radio button': click_and_focused(node) elif node.roleName == 'menu item' \ or node.roleName == 'check menu item': point_and_focused(node) node.click() elif node.roleName == 'push button': logger.info("Click on push button.") point_and_pointed(node) node.click() else: logger.info("Click on widget.") x, y = node.position assert x >= 0, "Node position X isn't positive: %s." % x assert y >= 0, "Node position Y isn't positive: %s." % y pointX = x + node.size[0] / 2 pointY = y + node.size[1] / 2 rawinput.click(pointX, pointY)
def startViaMenu(self, throughCategories = False): self.parseDesktopFile() if self.forceKill and self.isRunning(): self.kill() sleep(2) assert not self.isRunning(), "Application cannot be stopped" try: gnomeShell = root.application('gnome-shell') pressKey('Super_L') sleep(6) if throughCategories: # menu Applications x, y = getDashIconPosition('Show Applications') absoluteMotion(x, y) time.sleep(1) click(x, y) time.sleep(4) # time for all the oversized app icons to appear # submenu that contains the app submenu = gnomeShell.child( name=self.getMenuGroups(), roleName='list item') submenu.click() time.sleep(4) # the app itself app = gnomeShell.child( name=self.getName(), roleName='label') app.click() else: typeText(self.getName()) sleep(2) pressKey('Enter') assert self.isRunning(), "Application failed to start" except SearchError: print("!!! Lookup error while passing the path") return root.application(self.a11yAppName)
def startViaMenu(self, throughCategories=False): self.parseDesktopFile() if self.forceKill and self.isRunning(): self.kill() sleep(2) assert not self.isRunning(), "Application cannot be stopped" try: gnomeShell = root.application('gnome-shell') pressKey('Super_L') sleep(6) if throughCategories: # menu Applications x, y = getDashIconPosition('Show Applications') absoluteMotion(x, y) time.sleep(1) click(x, y) time.sleep(4) # time for all the oversized app icons to appear # submenu that contains the app submenu = gnomeShell.child(name=self.getMenuGroups(), roleName='list item') submenu.click() time.sleep(4) # the app itself app = gnomeShell.child(name=self.getName(), roleName='label') app.click() else: typeText(self.getName()) sleep(2) pressKey('Enter') assert self.isRunning(), "Application failed to start" except SearchError: print("!!! Lookup error while passing the path") return root.application(self.a11yAppName)
def receive_message(tb, version=0, signed=False, encrypted=False, attachment=None): tb.child(name='user@localhost', roleName='table row').doActionNamed('activate') tb.button('Get Messages').doActionNamed('press') tb.menuItem('Get All New Messages').doActionNamed('click') tb.child(name='Inbox.*', roleName='table row').doActionNamed('activate') config.searchCutoffCount = 5 try: tb.child(name='Encrypted Message .*|.*\.\.\. .*', roleName='table row').doActionNamed('activate') except tree.SearchError: pass finally: config.searchCutoffCount = defaultCutoffCount tb.child(name='.*{}.*'.format(subject), roleName='table row').doActionNamed('activate') # wait a little to TB decrypt/check the message time.sleep(2) # dogtail always add '$' at the end of regexp; and also "Escape all # parentheses, since grouping will never be needed here", so it can't be used # here either try: msg = tb.child(roleName='document web', name=subject + '$|Encrypted Message|\.\.\.') except tree.SearchError: msg = tb.child(roleName='document frame', name=subject + '$|Encrypted Message|\.\.\.') try: msg = msg.child(roleName='section') if len(msg.text) < 5 and msg.children: msg = msg.children[0] except tree.SearchError: msg = msg.child(roleName='paragraph') msg_body = msg.text print('Message body: {}'.format(msg_body)) assert msg_body.strip() == 'This is test message' # if msg.children: # msg_body = msg.children[0].text # else: # msg_body = msg.text config.searchCutoffCount = 5 try: if version >= 78: if signed or encrypted: # 'Message Security' can be either full dialog or a popup - # depending on TB version popup = False tb.findChild(GenericPredicate( name='View', roleName='menu')).doActionNamed('click') try: tb.findChild( GenericPredicate( name='Message Security Info', roleName='menu item')).doActionNamed('click') message_security = tb.child('Message Security') except tree.SearchError: # on debian there is no menu entry, but OpenPGP button # first close view menu tb.findChild(GenericPredicate( name='View', roleName='menu')).doActionNamed('click') tb.button('OpenPGP').doActionNamed('press') # 'Message Security - OpenPGP' is an internal label, # nested 2 levels into the popup message_security = tb.child('Message Security - OpenPGP') message_security = message_security.parent.parent popup = True if signed: message_security.child('Good Digital Signature') if encrypted: message_security.child('Message Is Encrypted') if not popup: message_security.button('OK').doActionNamed('press') else: message_security.parent.click() else: details = tb.button('Details') enigmail_status = details.parent.children[details.indexInParent - 1] print('Enigmail status: {}'.format(enigmail_status.text)) if signed: assert 'Good signature from' in enigmail_status.text if encrypted: assert 'Decrypted message' in enigmail_status.text except tree.SearchError: if signed or encrypted: raise finally: config.searchCutoffCount = defaultCutoffCount if attachment: # it can be either "1 attachment:" or "2 attachments" attachment_label = tb.child(name='.* attachment[:s]', roleName='label') offset = 0 if attachment_label.name == '1 attachment:': offset += 1 attachment_size = attachment_label.parent.children[ attachment_label.indexInParent + 1 + offset] assert attachment_size.text[0] != '0' attachment_save = attachment_label.parent.children[ attachment_label.indexInParent + 2 + offset].button('Save.*') try: # try child button first attachment_save.children[1].doActionNamed('press') except IndexError: # otherwise press main button to open the menu attachment_save.doActionNamed('press') # and choose "Save As..." attachment_save.menuItem('Save As.*|Save All.*').doActionNamed( 'click') # for some reasons some Thunderbird versions do not expose 'Attach File' # dialog through accessibility API, use xdotool instead if version >= 78: save_as = tb.findChild( GenericPredicate(name='Save All Attachments', roleName='file chooser')) click(*save_as.childNamed('Home').position) click(*save_as.childNamed('Desktop').position) save_as.childNamed('Open').doActionNamed('click') else: subprocess.check_call([ 'xdotool', 'search', '--name', 'Save Attachment', 'key', '--window', '0', '--delay', '30ms', 'ctrl+l', 'Home', 'type', '~/Desktop/\r' ]) # save_as = tb.dialog('Save .*Attachment.*') # places = save_as.child(roleName='table', # name='Places') # places.child(name='Desktop').click() # if 'attachments' in attachment_label.text: # save_as.button('Open').doActionNamed('click') # else: # save_as.button('Save').doActionNamed('click') time.sleep(1) with open(attachment, 'r') as f: orig_attachment = f.read() saved_basepath = os.path.expanduser('~/Desktop/{}'.format( os.path.basename(attachment))) if os.path.exists(saved_basepath): with open(saved_basepath) as f: received_attachment = f.read() assert received_attachment == orig_attachment print("Attachment content ok") elif os.path.exists(saved_basepath + '.pgp'): p = subprocess.Popen(['qubes-gpg-client-wrapper'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=open(saved_basepath + '.pgp', 'r')) (stdout, stderr) = p.communicate() if signed: if b'Good signature' not in stderr: print(stderr.decode()) raise AssertionError('no good signature found') print("Attachment signature ok") assert stdout.decode() == orig_attachment print("Attachment content ok - encrypted") else: raise Exception('Attachment {} not found'.format(saved_basepath)) if os.path.exists(saved_basepath + '.sig'): p = subprocess.Popen([ 'qubes-gpg-client-wrapper', '--verify', saved_basepath + '.sig', saved_basepath ], stdout=subprocess.PIPE, stderr=subprocess.PIPE) (stdout, stderr) = p.communicate() if signed: if b'Good signature' not in stderr: print(stderr.decode()) raise AssertionError('no good signature found') print("Attachment detached signature ok")
def startViaMenu(self): """ Start the app via Gnome Shell menu """ internCritical = (self.critical == 'start') #check if the app is running if self.forceKill and self.isRunning(): self.kill() sleep(2) if self.isRunning(): if internCritical: self.updateResult(False) #print "!!! The app is running but it shouldn't be" return False else: #print "*** The app has been killed succesfully" pass try: #panel button Activities gnomeShell = root.application('gnome-shell') activities = gnomeShell.child(name='Activities', roleName='label') activities.click() sleep(6) # time for overview to appear #menu Applications x, y = getDashIconPosition('Show Applications') absoluteMotion(x, y) sleep(1) click(x, y) sleep(4) # time for all the oversized app icons to appear #submenu that contains the app submenu = gnomeShell.child(name=self.getMenuGroups(), roleName='list item') submenu.click() sleep(4) #the app itself app = gnomeShell.child(name=self.getName(), roleName='label') app.click() #if there is a polkit if self.polkit: sleep(3) typeText(self.polkitPass) keyCombo('<Enter>') sleep(self.timeout) if self.isRunning(): #print "*** The app started successfully" if internCritical: self.updateResult(True) return True else: #print "!!! The app is not running but it should be" if internCritical: self.updateResult(False) return False except SearchError: #print "!!! Lookup error while passing the path" if internCritical: self.updateResult(False) return False
def test_click(self): btn = self.app.child('Builder') self.assertFalse(btn.selected) click(btn.position[0], btn.position[1]) self.assertTrue(btn.selected)
# selection mode for label1 in PAGE_LABELS: page = pages[label1] page.button.click() assert page.character_list.showing for label2 in PAGE_LABELS: if label2 == label1: continue assert not pages[label2].character_list.showing # character dialog page = pages['Punctuation'] page.button.click() x, y = page.character_list.position click(x + 10, y + 10) assert len(app.children) == 2 character_dialog = app.children[-1] assert character_dialog.name == 'Exclamation Mark' see_also_button = character_dialog.child('See Also') assert see_also_button.showing see_also_button.click() keyCombo('Escape') # recently used characters recently_used_page = Page(app, 'Recently Used') recently_used_page.button.click() x, y = recently_used_page.character_list.position click(x + 10, y + 10) assert len(app.children) == 2
def clickAbs(absPos, postDelay=0): ''' Click on the computer screen. ''' return rawinput.click(absPos[0], absPos[1])
def testRightClickOnDock(self, x, y): rawinput.click(x, y, 3)
def testClickScreenCenter(self): rawinput.click(int(utils.resolution.width/2), int(utils.resolution.height/2)) time.sleep(1)
if not toggle_button_node.isChecked: toggle_button_node.click() # close gnome-tweaks tweaks_node \ .child(name="Close", roleName=ROLE_PUSH_BUTTON) \ .click() # click on the graphical widget shell_window_node = tree.root.application("gnome-shell") \ .child(roleName=ROLE_WINDOW) panel_node = shell_window_node \ .child(name="Cpu", roleName=ROLE_LABEL) \ .findAncestor(predicate.GenericPredicate(roleName=ROLE_PANEL)) applet_position = ((shell_window_node.size[0] - 100), 0) # approximation rawinput.click(*applet_position) # find the cpu value strings = panel_node.getUserVisibleStrings() cpu_idx = strings.index("Cpu") + 1 cpu_value = int(strings[cpu_idx]) assert cpu_value >= 0 logging.debugLogger.log(f"{cpu_value=}") # open applet preference dialog perference_menu_item_node = panel_node \ .findAncestor(predicate.GenericPredicate(roleName=ROLE_PANEL)) \ .findAncestor(predicate.GenericPredicate(roleName=ROLE_PANEL)) \ .child(name="Preferences...", roleName=ROLE_LABEL) \ .findAncestor(predicate.GenericPredicate(roleName=ROLE_MENU_ITEM)) rawinput.click(*perference_menu_item_node.position)