def zoom_with_mouse_wheel(nr_of_times=1, zoom_type=None): """Zoom in/Zoom out using the mouse wheel. :param nr_of_times: Number of times the 'zoom in'/'zoom out' action should take place. :param zoom_type: Type of the zoom action('zoom in'/'zoom out') intended to be performed. :return: None. """ # MAC needs doubled number of mouse wheels to zoom in correctly. if OSHelper.is_mac(): nr_of_times *= 2 # Move focus in the middle of the page to be able to use the scroll. Mouse().move(Location(Screen.SCREEN_WIDTH // 4, Screen.SCREEN_HEIGHT // 2)) for i in range(nr_of_times): if OSHelper.is_mac(): key_down('command') else: key_down('ctrl') Mouse().scroll(dy=zoom_type, dx=0) if OSHelper.is_mac(): key_up('command') else: key_up('ctrl') time.sleep(Settings.DEFAULT_UI_DELAY) Mouse().move(Location(0, 0))
def maximize_window(): """Maximize the browser window to fill the screen. This is NOT Full Screen mode. """ if OSHelper.is_mac(): # There is no keyboard shortcut for this on Mac. We'll do it the old fashioned way. # This image is of the three window control buttons at top left of the window. # We have to resize the window to ensure maximize works properly in all cases. window_controls_pattern = Pattern('window_controls.png') controls_location = find(window_controls_pattern) xcoord = controls_location.x ycoord = controls_location.y width, height = window_controls_pattern.get_size() drag_start = Location(xcoord + 70, ycoord + 5) drag_end = Location(xcoord + 75, ycoord + 5) Mouse().drag_and_drop(drag_start, drag_end, duration=0.1) # Alt key changes maximize button from full screen to maximize window. maximize_button = window_controls_pattern.target_offset( width / 2 - 3, 0) key_down(Key.ALT) click(maximize_button) key_up(Key.ALT) elif OSHelper.is_windows(): type(text=Key.UP, modifier=KeyModifier.WIN) else: type(text=Key.UP, modifier=[KeyModifier.CTRL, KeyModifier.META]) time.sleep(Settings.DEFAULT_UI_DELAY)
def wait(ps, timeout=None, region=None) -> bool or FindError: """Verify that a Pattern or str appears. :param ps: String or Pattern. :param timeout: Number as maximum waiting time in seconds. :param region: Rectangle object in order to minimize the area. :return: True if found, otherwise raise FindError. """ if isinstance(ps, Pattern): if timeout is None: timeout = Settings.auto_wait_timeout image_found = image_find(ps, timeout, region) if image_found is not None: if Settings.highlight: highlight(region=region, ps=ps, location=[image_found]) return True else: raise FindError('Unable to find image %s' % ps.get_filename()) elif isinstance(ps, str): text_found = text_find(ps, region) if len(text_found) > 0: if Settings.highlight: highlight(region=region, ps=ps, text_location=text_found) return Location(text_found[0].x, text_found[0].y) else: raise FindError('Unable to find text %s' % ps) else: raise ValueError('Invalid input')
def restore_window_from_taskbar(option=None): """Restore firefox from task bar.""" if OSHelper.is_mac(): try: click(Pattern('main_menu_window.png')) if option == "browser_console": click(Pattern('window_browser_console.png')) else: click(Pattern('window_firefox.png')) except FindError: raise APIHelperError('Restore window from taskbar unsuccessful.') elif OSHelper.get_os_version() == 'win7': try: click(Pattern('firefox_start_bar.png')) if option == "library_menu": click(Pattern('firefox_start_bar_library.png')) if option == "browser_console": click(Pattern('firefox_start_bar_browser_console.png')) except FindError: raise APIHelperError('Restore window from taskbar unsuccessful.') else: type(text=Key.TAB, modifier=KeyModifier.ALT) if OSHelper.is_linux(): Mouse().move(Location(0, 50)) time.sleep(Settings.DEFAULT_UI_DELAY)
def find_all(ps: Pattern or str, region: Rectangle = None): """Look for all matches of a Pattern or image. :param ps: Pattern or String. :param region: Rectangle object in order to minimize the area. :return: Location object or FindError. """ if isinstance(ps, Pattern): images_found = match_template(ps, region, MatchTemplateType.MULTIPLE) if len(images_found) > 0: if Settings.highlight: highlight(region=region, ps=ps, location=images_found) return images_found else: raise FindError('Unable to find image %s' % ps.get_filename()) elif isinstance(ps, str): locations = [] text_found = text_find_all(ps, region) if len(text_found) > 0: if Settings.highlight: highlight(region=region, ps=ps, text_location=text_found) for text in text_found: locations.append(Location(text.x, text.y)) return locations else: raise FindError('Unable to find text %s' % ps)
def apply_alignment(self, align: Alignment = Alignment.TOP_LEFT): """Returns rectangle location based on alignment. :param align: Alignment could be top_left, center, top_right, bottom_left, bottom_right. :return: Location object. """ if align is Alignment.CENTER: return Location(self.x + int(self.width / 2), self.y + int(self.height / 2)) elif align is Alignment.TOP_RIGHT: return Location(self.x + self.width, self.y) elif align is Alignment.BOTTOM_LEFT: return Location(self.x, self.y + self.height) elif align is Alignment.BOTTOM_RIGHT: return Location(self.x + self.width, self.y + self.height) else: return Location(self.x, self.y)
def target_offset(self, dx: int, dy: int): """Add offset to Pattern from top left. :param int dx: x offset from center. :param int dy: y offset from center. :return: A new pattern object. """ new_pattern = Pattern(self.image_name, from_path=self.image_path) new_pattern._target_offset = Location(dx, dy) return new_pattern
def find_window_controls(window_type): """Find window controls for main and auxiliary windows. :param window_type: Controls for a specific window type. :return: None. """ if window_type == 'auxiliary': Mouse().move(Location(1, 300)) if OSHelper.is_mac(): try: wait(AuxiliaryWindow.RED_BUTTON_PATTERN.similar(0.9), 5) logger.debug('Auxiliary window control found.') except FindError: raise APIHelperError('Can\'t find the auxiliary window controls, aborting.') else: if OSHelper.is_linux(): Mouse().move(Location(80, 0)) try: wait(AuxiliaryWindow.CLOSE_BUTTON, 5) logger.debug('Auxiliary window control found.') except FindError: raise APIHelperError( 'Can\'t find the auxiliary window controls, aborting.') elif window_type == 'main': if OSHelper.is_mac(): try: wait(MainWindow.MAIN_WINDOW_CONTROLS.similar(0.9), 5) logger.debug('Main window controls found.') except FindError: raise APIHelperError('Can\'t find the Main window controls, aborting.') else: try: if OSHelper.is_linux(): reset_mouse() wait(MainWindow.CLOSE_BUTTON, 5) logger.debug('Main window control found.') except FindError: raise APIHelperError( 'Can\'t find the Main window controls, aborting.') else: raise APIHelperError('Window Type not supported.')
def move(self, location: Location = None, duration: float = None): """Mouse move with tween. :param location: Location , image name or Pattern. :param duration: Speed of mouse movement from current mouse location to target. :return: None. """ if location is None: location = Location(0, 0) if duration is None: duration = Settings.move_mouse_delay def set_mouse_position(loc_x, loc_y): self.mouse.position = (int(loc_x), int(loc_y)) def smooth_move_mouse(from_x, from_y, to_x, to_y): num_steps = int(duration / 0.05) sleep_amount = 0 try: sleep_amount = duration / num_steps except ZeroDivisionError: pass steps = [ _get_point_on_line(from_x, from_y, to_x, to_y, n / num_steps) for n in range(num_steps) ] steps.append((to_x, to_y)) for tween_x, tween_y in steps: tween_x = int(round(tween_x)) tween_y = int(round(tween_y)) set_mouse_position(tween_x, tween_y) time.sleep(sleep_amount) return smooth_move_mouse(self.mouse.position[0], self.mouse.position[1], location.x, location.y)
def find(ps: Pattern or str, region: Rectangle = None) -> Location or FindError: """Look for a single match of a Pattern or image. :param ps: Pattern or String. :param region: Rectangle object in order to minimize the area. :return: Location object. """ if isinstance(ps, Pattern): image_found = match_template(ps, region, MatchTemplateType.SINGLE) if len(image_found) > 0: if Settings.highlight: highlight(region=region, ps=ps, location=image_found) return image_found[0] else: raise FindError('Unable to find image %s' % ps.get_filename()) elif isinstance(ps, str): text_found = text_find(ps, region) if len(text_found) > 0: if Settings.highlight: highlight(region=region, ps=ps, text_location=text_found) return Location(text_found[0].x, text_found[0].y) else: raise FindError('Unable to find text %s' % ps)
def get_top_left_coordinates(self) -> Location: """Returns a Location object for the top left of te screen.""" return Location(self.x, self.y)
def create_region_from_patterns(top=None, bottom=None, left=None, right=None, padding_top=None, padding_bottom=None, padding_left=None, padding_right=None): """Returns a region created from combined area of one or more patterns. Argument names are just for convenience and don't influence outcome. :param top: Top pattern used to generate the region. :param bottom: Bottom pattern used to generate the region. :param left: Left pattern used to generate the region. :param right: Right pattern used to generate the region. :param padding_top: Padding to be added to the pattern's top. :param padding_bottom: Padding to be added to the pattern's bottom. :param padding_left: Padding to be added to the pattern's left. :param padding_right: Padding to be added to the pattern's right. :return: region created from combined area of one or more patterns. """ patterns = [] if top: patterns.append(top) if bottom: patterns.append(bottom) if left: patterns.append(left) if right: patterns.append(right) if len(patterns) == 0: raise ValueError('One or more patterns required.') logger.debug('Creating region from %s pattern(s).' % len(patterns)) a, b = (Screen().width, Screen().height) p1 = Location(a, b) p2 = Location(0, 0) for pattern in patterns: if exists(pattern, 5): current_pattern = find(pattern) if current_pattern.x < p1.x: p1.x = current_pattern.x if current_pattern.y < p1.y: p1.y = current_pattern.y w, h = pattern.get_size() if current_pattern.x + w > p2.x: p2.x = current_pattern.x + w if current_pattern.y + h > p2.y: p2.y = current_pattern.y + h else: raise FindError('Pattern not found: %s ' % pattern) found_region = Region(p1.x, p1.y, p2.x - p1.x, p2.y - p1.y) if padding_top or padding_bottom or padding_left or padding_right: logger.debug('Adding padding to region.') if padding_top: found_region.y -= padding_top found_region.height += padding_top if padding_bottom: found_region.height += padding_bottom if padding_left: found_region.x -= padding_left found_region.width += padding_left if padding_right: found_region.width += padding_right return found_region
def reset_mouse(): """Reset mouse position to location (0, 0).""" Mouse().move(Location(0, 0))
def get_center(self) -> Location: """Returns a Location object for the center of te screen.""" return Location(int((self.x + self.width) / 2), int((self.y + self.height) / 2))
def get_bottom_right_coordinates(self) -> Location: """Returns a Location object for the bottom right of te screen.""" return Location(self.x + self.width, self.y + self.height)
def get_bottom_left_coordinates(self) -> Location: """Returns a Location object for the bottom left of te screen.""" return Location(self.x, self.y + self.height)
def get_top_right_coordinates(self) -> Location: """Returns a Location object for the top right of te screen.""" return Location(self.x + self.width, self.y)