def __init__(self, screen_id: int = 0): self.screen_id = screen_id self.screen_list = DisplayCollection[screen_id] self._bounds = DisplayCollection[screen_id].bounds Region.__init__( self, self._bounds.x, self._bounds.y, self._bounds.width, self._bounds.height, )
def open_library_menu(option): """Open a specific option from 'Library' menu with an option as an argument. :param option: Library menu option to be selected. :return: None """ library_menu_pattern = NavBar.LIBRARY_MENU library_option_list = { 'Bookmarks': 1, 'View Pocket List': 2, 'History': 3, 'Downloads': 4, 'Synced Tabs': 5 } if OSHelper.is_windows(): value = 5 else: value = 4 try: wait(library_menu_pattern, 10) region = Region( image_find(library_menu_pattern).x - Screen().width / value, image_find(library_menu_pattern).y, Screen().width / value, Screen().height / value, ) logger.debug("Library menu found.") except FindError: raise APIHelperError( "Can't find the library menu in the page, aborting test.") else: time.sleep(Settings.DEFAULT_UI_DELAY_LONG) click(library_menu_pattern) time.sleep(Settings.DEFAULT_UI_DELAY_SHORT) try: time.sleep(Settings.DEFAULT_UI_DELAY_SHORT) region.wait(LibraryMenu.BOOKMARKS_OPTION, 10) option_number_in_library_list = library_option_list[option] for _ in range(option_number_in_library_list): time.sleep(0.5) type(Key.TAB) time.sleep(1) type(Key.ENTER) except FindError: raise APIHelperError( "Can't find the option in the page, aborting test.")
def generate_region_by_markers(top_left_marker_img=None, bottom_right_marker_img=None): """Generate a region starting from 2 markers. :param top_left_marker_img: Top left pattern used to generate the region. :param bottom_right_marker_img: Bottom right pattern used to generate the region. :return: Screen region generated. """ try: wait(top_left_marker_img, 10) exists(bottom_right_marker_img, 10) except FindError: raise FindError("Unable to find page markers.") top_left_pos = find(top_left_marker_img) bottom_right_pos = find(bottom_right_marker_img) marker_width, marker_height = bottom_right_marker_img.get_size() return Region( top_left_pos.x, top_left_pos.y, (bottom_right_pos.x + marker_width), bottom_right_pos.y - top_left_pos.y + marker_height, )
def find_in_region_from_pattern( outer_pattern: Pattern, inner_pattern: Pattern, outer_pattern_timeout=Settings.auto_wait_timeout, inner_pattern_timeout=Settings.auto_wait_timeout, ): """ Finds pattern in region created from another pattern :param outer_pattern: Pattern for region creation :param inner_pattern: Pattern to find in region :param outer_pattern_timeout: Time to finding outer_pattern :param inner_pattern_timeout: Time to finding inner_pattern, :return: Boolean. True if inner_pattern found in outer_pattern region :raises: ValueError and APIHelperError """ if not isinstance(outer_pattern, Pattern) or not isinstance( inner_pattern, Pattern): raise ValueError(INVALID_GENERIC_INPUT) try: wait(outer_pattern, outer_pattern_timeout) logger.debug("Outer pattern found.") except FindError: raise APIHelperError("Can't find the outer pattern.") width, height = outer_pattern.get_size() region = Region( image_find(outer_pattern).x, image_find(outer_pattern).y, width, height) pattern_found = exists(inner_pattern, inner_pattern_timeout, region=region) return pattern_found
def select_throttling(option): network_pattern = Pattern("network.png").similar(0.6) throttling_menu_pattern = Pattern("no_throttling.png").similar(0.6) region_ll = Screen.LOWER_LEFT_CORNER region_lr = Region.screen_regions(Screen.LOWER_RIGHT_CORNER, "RIGHT_THIRD") open_web_console() try: region_ll.wait(network_pattern, 30) region_ll.click(network_pattern) except FindError: raise APIHelperError( "Can't find the network menu in the page, aborting test.") try: region_lr.wait(throttling_menu_pattern, 10) region_lr.click(throttling_menu_pattern) except FindError: raise APIHelperError( "Can't find the throttling menu in the page, aborting test.") for i in range(option + 1): type(Key.DOWN) type(Key.ENTER)
def open_library_menu(option): """Open the Library menu with an option as argument. :param option: Library menu option. :return: Custom region created for a more efficient and accurate image pattern search. """ library_menu_pattern = NavBar.LIBRARY_MENU if OSHelper.is_windows(): value = 5 else: value = 4 try: wait(library_menu_pattern, 10) region = Region( image_find(library_menu_pattern).x - Screen().width / value, image_find(library_menu_pattern).y, Screen().width / value, Screen().height / value, ) logger.debug("Library menu found.") except FindError: raise APIHelperError( "Can't find the library menu in the page, aborting test.") else: time.sleep(Settings.DEFAULT_UI_DELAY_LONG) click(library_menu_pattern) time.sleep(Settings.DEFAULT_UI_DELAY_SHORT) try: time.sleep(Settings.DEFAULT_UI_DELAY_SHORT) region.wait(option, 10) logger.debug("Option found.") region.click(option) return region except FindError: raise APIHelperError( "Can't find the option in the page, aborting test.")
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 cancel_in_progress_downloads_from_the_library(private_window=False): # Open the 'Show Downloads' window and cancel all 'in progress' downloads. global cancel_downloads if private_window: steps = show_all_downloads_from_library_menu_private_window() logger.debug('Creating a region for Private Library window.') try: find_back_button = find(NavBar.BACK_BUTTON) except FindError: raise FindError('Could not get the coordinates of the nav bar back button.') try: find_hamburger_menu = find(NavBar.HAMBURGER_MENU) except FindError: raise FindError('Could not get the coordinates of the hamburger menu.') region = Region(find_back_button.x - 10, find_back_button.y, Screen.SCREEN_WIDTH, Screen.SCREEN_HEIGHT) else: steps = open_show_all_downloads_window_from_library_menu() logger.debug('Creating a region for Non-private Library window.') expected = exists(Library.TITLE, 10) assert expected is True, 'Library successfully opened.' try: find_library = find(Library.TITLE) except FindError: raise FindError('Could not get the x-coordinate of the library window title.') try: find_clear_downloads = find(Library.CLEAR_DOWNLOADS) except FindError: raise FindError('Could not get the x-coordinate of the clear_downloads button.') clear_downloads_width, clear_downloads_height = Library.CLEAR_DOWNLOADS.get_size() region = Region(find_library.x - 10, find_library.y, (find_clear_downloads.x + clear_downloads_width + 20) - find_library.x, 500) # Cancel all 'in progress' downloads. expected = region.exists(DownloadManager.DownloadsPanel.DOWNLOAD_CANCEL, 5) expected_highlighted = region.exists(DownloadManager.DownloadsPanel.DOWNLOAD_CANCEL_HIGHLIGHTED) if expected or expected_highlighted: steps.append(Step(expected, 'The Cancel Download button is displayed properly.')) cancel_downloads = True expected_cancel = True else: steps.append(Step(True, 'There are no downloads to be cancelled.')) cancel_downloads = False cancel_pattern = DownloadManager.DownloadsPanel.DOWNLOAD_CANCEL if expected \ else DownloadManager.DownloadsPanel.DOWNLOAD_CANCEL_HIGHLIGHTED if cancel_downloads: while expected_cancel: expected_cancel = region.exists(cancel_pattern, 10) if expected_cancel: click(cancel_pattern) if not private_window: hover(Library.TITLE) steps.append(Step(True, 'All downloads were cancelled.')) if private_window: close_tab() else: click_window_control('close') return steps
class Screen(Region): """Class Screen is the representation for a physical monitor where the capturing process (grabbing a rectangle from a screenshot). It is used for further processing with find operations. For Multi Monitor Environments it contains features to map to the relevant monitor. """ def __init__(self, screen_id: int = 0): self.screen_id = screen_id self.screen_list = DisplayCollection[screen_id] self._bounds = DisplayCollection[screen_id].bounds Region.__init__( self, self._bounds.x, self._bounds.y, self._bounds.width, self._bounds.height, ) SCREEN_WIDTH, SCREEN_HEIGHT = pyautogui.size() screen_region = Region(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT) TOP_HALF = Region.screen_regions(screen_region, "TOP_HALF") BOTTOM_HALF = Region.screen_regions(screen_region, "BOTTOM_HALF") LEFT_HALF = Region.screen_regions(screen_region, "LEFT_HALF") RIGHT_HALF = Region.screen_regions(screen_region, "RIGHT_HALF") TOP_THIRD = Region.screen_regions(screen_region, "TOP_THIRD") MIDDLE_THIRD_HORIZONTAL = Region.screen_regions( screen_region, "MIDDLE_THIRD_HORIZONTAL" ) BOTTOM_THIRD = Region.screen_regions(screen_region, "BOTTOM_THIRD") LEFT_THIRD = Region.screen_regions(screen_region, "LEFT_THIRD") MIDDLE_THIRD_VERTICAL = Region.screen_regions( screen_region, "MIDDLE_THIRD_VERTICAL" ) RIGHT_THIRD = Region.screen_regions(screen_region, "RIGHT_THIRD") UPPER_LEFT_CORNER = Region.screen_regions(screen_region, "UPPER_LEFT_CORNER") UPPER_RIGHT_CORNER = Region.screen_regions(screen_region, "UPPER_RIGHT_CORNER") LOWER_LEFT_CORNER = Region.screen_regions(screen_region, "LOWER_LEFT_CORNER") LOWER_RIGHT_CORNER = Region.screen_regions(screen_region, "LOWER_RIGHT_CORNER") def __repr__(self): return "%s(x: %r, y: %r, size: %r x %r)" % ( self.__class__.__name__, self._bounds.x, self.y, self._bounds.width, self._bounds.height, ) def get_number_screens(self) -> int: """Get the number of screens in a multi-monitor environment at the time the script is running.""" return len(self.screen_list) def get_bounds(self) -> Rectangle: """Get the dimensions of monitor represented by the screen object.""" return self._bounds