コード例 #1
0
ファイル: Windows.py プロジェクト: krehl/rpaframework
    def send_keys_to_input(
        self,
        keys_to_type: str,
        with_enter: bool = True,
        send_delay: float = 0.5,
        enter_delay: float = 1.5,
    ) -> None:
        """Send keys to windows and add ENTER if `with_enter` is True

        At the end of send_keys there is by default 1.0 second delay.
        At the end of ENTER there is by default 3.5 second delay.

        :param keys_to_type: keys to type into Windows
        :param with_enter: send ENTER if `with_enter` is True
        :param send_delay: delay after send_keys
        :param enter_delay: delay after ENTER
        """
        # Set keyboard layout for Windows platform
        if platform.system() == "Windows":
            win32api.LoadKeyboardLayout("00000409", 1)

        self.send_keys(keys_to_type)
        delay(send_delay)
        if with_enter:
            self.send_keys("{ENTER}")
            delay(enter_delay)
コード例 #2
0
    def drag_and_drop(
        self,
        source: str,
        destination: str,
        start_delay: float = 2.0,
        end_delay: float = 0.5,
    ) -> None:
        """Drag mouse from source to destination while holding the left mouse button.

        :param source:      Locator for start position
        :param destination: Locator for destination position
        :param start_delay: Delay in seconds after pressing down mouse button
        :param end_delay:   Delay in seconds before releasing mouse button
        """
        if self._error:
            raise self._error
        src = self.ctx.find_element(source)
        dst = self.ctx.find_element(destination)

        self.logger.info("Dragging from (%d, %d) to (%d, %d)", *src, *dst)

        self._move(src)
        self.press_mouse_button()
        delay(start_delay)
        self._move(dst)
        delay(end_delay)
        self.release_mouse_button()
コード例 #3
0
ファイル: mouse.py プロジェクト: zodiitti/rpaframework
    def _click(
        self,
        action: Action = Action.click,
        location: Optional[Union[Point, Region]] = None,
    ) -> None:
        """Perform defined mouse action, and optionally move to given point first."""
        # pylint: disable=C0415
        from pynput.mouse import Button

        action = to_action(action)

        if location:
            self._move(location)
            delay(0.05)

        self.logger.info("Performing mouse action: %s", action)

        if action is Action.click:
            self._mouse.click(Button.left)
        elif action is Action.double_click:
            self._mouse.click(Button.left, 2)
        elif action is Action.triple_click:
            self._mouse.click(Button.left, 3)
        elif action is Action.right_click:
            self._mouse.click(Button.right)
        else:
            # TODO: mypy should handle enum exhaustivity validation
            raise ValueError(f"Unsupported action: {action}")
コード例 #4
0
ファイル: Windows.py プロジェクト: krehl/rpaframework
    def get_window_elements(
        self,
        screenshot: bool = False,
        element_json: bool = False,
        outline: bool = False,
    ) -> Any:
        """Get element information about all window dialog controls
        and their descendants.

        :param screenshot: save element screenshot if True, defaults to False
        :param element_json: save element json if True, defaults to False
        :param outline: highlight elements if True, defaults to False
        :return: all controls and all elements
        """
        if self.dlg is None:
            raise ValueError("No dialog open")

        ctrls = [self.dlg]
        if hasattr(self.dlg, "descendants"):
            ctrls += self.dlg.descendants()

        elements, controls = [], []
        for _, ctrl in enumerate(ctrls):
            if not hasattr(ctrl, "element_info"):
                continue

            filename = clean_filename(
                f"locator_{self.windowtitle}_ctrl_{ctrl.element_info.name}")

            if screenshot and len(ctrl.element_info.name) > 0:
                self.screenshot(filename, ctrl=ctrl)
            if outline:
                ctrl.draw_outline(colour="red", thickness=4)
                delay(0.2)
                ctrl.draw_outline(colour=0x000000, thickness=4)

            element = self._parse_element_attributes(element=ctrl)
            if element_json:
                write_element_info_as_json(element, filename)

            controls.append(ctrl)
            elements.append(element)

        if element_json:
            write_element_info_as_json(
                elements,
                clean_filename(f"locator_{self.windowtitle}_all_elements"))

        return controls, elements
コード例 #5
0
ファイル: Windows.py プロジェクト: krehl/rpaframework
    def switch_to_application(self, app_id: int) -> None:
        """Switch to application by id.

        :param app_id: application's id
        :raises ValueError: if application is not found by given id
        """
        if app_id and app_id in self._apps.keys():
            app = self.get_app(app_id)
            self._active_app_instance = app_id
            self.app = app["app"]
            self.open_dialog(app["windowtitle"])
            delay(0.5)
            self.restore_dialog(app["windowtitle"])
        else:
            raise ValueError(f"No open application with id '{app_id}'")
コード例 #6
0
ファイル: Windows.py プロジェクト: krehl/rpaframework
    def mouse_click_coords(self,
                           x: int,
                           y: int,
                           ctype: str = "click",
                           delay_time: float = None) -> None:
        """Click at coordinates on desktop

        :param x: horizontal coordinate on the windows to click
        :param y: vertical coordinate on the windows to click
        :param ctype: click type "click", "right" or "double", defaults to "click"
        :param delay: delay in seconds after, default is no delay
        """
        self.click_type(x, y, ctype)
        if delay_time:
            delay(delay_time)
コード例 #7
0
ファイル: Windows.py プロジェクト: krehl/rpaframework
    def open_using_run_dialog(self, executable: str, windowtitle: str) -> int:
        """Open application using Windows run dialog.
        Window title name is required to get handle on the application.

        :param executable: name of the executable
        :param windowtitle: name of the window
        :return: application instance id
        """
        self.send_keys("{VK_LWIN down}r{VK_LWIN up}")
        delay(1)

        self.send_keys_to_input(executable)

        params = {"windowtitle": windowtitle, "executable": executable}
        return self._add_app_instance(params=params, dialog=True)
コード例 #8
0
ファイル: Windows.py プロジェクト: krehl/rpaframework
    def open_from_search(self, executable: str, windowtitle: str) -> int:
        """Open application using Windows search dialog.
        Window title name is required to get handle on the application.

        :param executable: name of the executable
        :param windowtitle: name of the window
        :return: application instance id
        """
        self.logger.info("Run from start menu: %s", executable)
        self.send_keys("{LWIN}")
        delay(1)

        self.send_keys_to_input(executable)

        params = {"windowtitle": windowtitle, "executable": executable}
        return self._add_app_instance(params=params, dialog=True)
コード例 #9
0
ファイル: Windows.py プロジェクト: krehl/rpaframework
    def drag_and_drop(
        self,
        src: Any,
        target: Any,
        src_locator: str,
        target_locator: str = None,
        handle_ctrl_key: bool = False,
        drop_delay: float = 2.0,
    ) -> None:
        """Drag elements from source and drop them on target.

        Please note that if CTRL is not pressed down during drag and drop then
        operation is MOVE operation, on CTRL down the operation is COPY operation.

        There will be also overwrite notification if dropping over existing files.

        :param src: application object or instance id
        :param target: application object or instance id
        :param ssrc_locator: elements to move
        :param target_locator: target element to drop source elements into
        :param handle_ctrl_key: True if keyword should press CTRL down dragging
        :param drop_delay: how many seconds to wait until releasing mouse drop,
            default 2.0
        :raises ValueError: on validation errors
        """
        if isinstance(src, int):
            src = self.get_app(src)
        if isinstance(target, int):
            target = self.get_app(target)

        selections, source_x, source_y = self._select_elements_for_drag(
            src, src_locator)
        target_x, target_y = self._validate_target(target, target_locator)

        self.logger.info(
            "Dragging %d elements from (%d,%d) to (%d,%d)",
            len(selections),
            source_x,
            source_y,
            target_x,
            target_y,
        )

        if handle_ctrl_key:
            self.send_keys("{VK_LCONTROL down}")
            delay(0.5)
        # Select elements by mouse clicking

        for idx, selection in enumerate(selections):
            self.logger.debug("Selecting item %d by mouse_click", idx)
            pywinauto.mouse.click(coords=(selection[0], selection[1]))

        # Start drag from the last item
        pywinauto.mouse.press(coords=(source_x, source_y))
        delay(1)
        pywinauto.mouse.move(coords=(target_x, target_y))

        self.logger.debug("Cursor position: %s", win32api.GetCursorPos())
        delay(drop_delay)
        pywinauto.mouse.click(coords=(target_x, target_y))
        pywinauto.mouse.release(coords=(target_x, target_y))

        if handle_ctrl_key:
            self.send_keys("{VK_LCONTROL up}")
            delay(0.5)
        # Deselect elements by mouse clicking
        for selection in selections:
            self.logger.debug("Deselecting item by mouse_click")
            self.mouse_click_coords(selection[0], selection[1])