Esempio n. 1
0
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))
Esempio n. 2
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)
Esempio n. 3
0
def match_template(
    pattern: Pattern,
    region: Rectangle = None,
    match_type: MatchTemplateType = MatchTemplateType.SINGLE,
):
    """Find a pattern in a Region or full screen

    :param Pattern pattern: Image details
    :param Region region: Region object.
    :param MatchTemplateType match_type: Type of match_template (single or multiple)
    :return: Location.
    """
    if region is None:
        region = DisplayCollection[0].bounds

    locations_list = []
    save_img_location_list = []
    if not isinstance(match_type, MatchTemplateType):
        logger.warning("%s should be an instance of `%s`" %
                       (match_type, MatchTemplateType))
        return []
    try:
        stack_image = ScreenshotImage(
            region=region, screen_id=_region_in_display_list(region))
        precision = pattern.similarity
        if precision == 0.99:
            logger.debug("Searching image with similarity %s" % precision)
            res = cv2.matchTemplate(stack_image.get_color_array(),
                                    pattern.get_color_array(), FIND_METHOD)
        else:
            logger.debug("Searching image with similarity %s" % precision)
            res = cv2.matchTemplate(stack_image.get_gray_array(),
                                    pattern.get_gray_array(), FIND_METHOD)

        if match_type is MatchTemplateType.SINGLE:
            min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
            logger.debug("Min location %s and max location %s" %
                         (min_val, max_val))
            if max_val >= precision:
                locations_list.append(
                    Location(max_loc[0] + region.x, max_loc[1] + region.y))
                save_img_location_list.append(Location(max_loc[0], max_loc[1]))
        elif match_type is MatchTemplateType.MULTIPLE:
            loc = np.where(res >= precision)
            for pt in zip(*loc[::-1]):
                save_img_location = Location(pt[0], pt[1])
                location = Location(pt[0] + region.x, pt[1] + region.y)
                save_img_location_list.append(save_img_location)
                locations_list.append(location)

        save_debug_image(pattern, stack_image, save_img_location_list)

    except ScreenshotError:
        logger.warning("Screenshot failed.")
        return []

    return locations_list
Esempio n. 4
0
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):
        if not Settings.OCR_ENABLED:
            raise FindError("OCR is not enabled, cannot search for text.")
        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)
Esempio n. 5
0
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")
Esempio n. 6
0
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)
Esempio n. 7
0
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)
Esempio n. 8
0
    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)
Esempio n. 9
0
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.")
Esempio n. 10
0
    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.
        """
        self.load_pattern()
        new_pattern = Pattern(self.image_name, from_path=self.image_path)
        new_pattern._target_offset = Location(dx, dy)
        return new_pattern
Esempio n. 11
0
    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)
Esempio n. 12
0
    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
Esempio n. 13
0
def reset_mouse():
    """Reset mouse position to location (0, 0)."""
    Mouse().move(Location(0, 0))
Esempio n. 14
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))
Esempio n. 15
0
 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)
Esempio n. 16
0
 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)
Esempio n. 17
0
 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)
Esempio n. 18
0
 def get_top_left_coordinates(self) -> Location:
     """Returns a Location object for the top left of te screen."""
     return Location(self.x, self.y)