Skip to content

Commit 4069c77

Browse files
ENH: Improving Win Apps module to support pywinauto's Desktop class
1 parent 5fefa6d commit 4069c77

File tree

2 files changed

+32
-16
lines changed

2 files changed

+32
-16
lines changed

botcity/core/application/functions.py

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import time
2+
from typing import Union
3+
from pywinauto import Desktop
24
from pywinauto.timings import TimeoutError
3-
from pywinauto.findwindows import ElementNotFoundError
5+
from pywinauto.findwindows import ElementNotFoundError, WindowNotFoundError
46
from pywinauto.application import Application, WindowSpecification
57
from .utils import Backend
68
from .. import config
79

810

9-
def connect(backend=Backend.WIN_32, timeout=60000, **connection_selectors) -> Application:
11+
def connect(backend=Backend.WIN_32, timeout=60000,
12+
**connection_selectors) -> Union[Application, WindowSpecification]:
1013
"""
1114
Connects to an instance of an open application.
1215
Use this method to be able to access application windows and elements.
@@ -21,30 +24,41 @@ def connect(backend=Backend.WIN_32, timeout=60000, **connection_selectors) -> Ap
2124
](https://documentation.botcity.dev/frameworks/desktop/windows-apps/).
2225
2326
Returns
24-
app (Application): The Application instance.
27+
app (Application | WindowSpecification): The Application/Window instance.
2528
"""
2629
connect_exception = None
2730
start_time = time.time()
2831
while True:
2932
elapsed_time = (time.time() - start_time) * 1000
3033
if elapsed_time > timeout:
31-
if connect_exception:
32-
raise connect_exception
33-
return None
34+
break
3435
try:
3536
app = Application(backend=backend).connect(**connection_selectors)
3637
return app
3738
except Exception as e:
3839
connect_exception = e
3940
time.sleep(config.DEFAULT_SLEEP_AFTER_ACTION/1000.0)
4041

42+
if "path" in connection_selectors.keys():
43+
connection_selectors.pop("path")
4144

42-
def find_window(app: Application, waiting_time=10000, **selectors) -> WindowSpecification:
45+
if not connection_selectors:
46+
if connect_exception:
47+
raise connect_exception
48+
return None
49+
50+
app = Desktop(backend=backend).window(**connection_selectors)
51+
if not app.exists():
52+
raise WindowNotFoundError(f"Unable to find an app using these criteria: {connection_selectors}")
53+
return app
54+
55+
def find_window(app: Union[Application, WindowSpecification],
56+
waiting_time=10000, **selectors) -> WindowSpecification:
4357
"""
4458
Find a window of the currently connected application using the available selectors.
4559
4660
Args:
47-
app (Application): The connected application.
61+
app (Application | WindowSpecification): The connected application.
4862
waiting_time (int, optional): Maximum wait time (ms) to search for a hit.
4963
Defaults to 10000ms (10s).
5064
**selectors: Attributes that can be used to filter an element.
@@ -62,14 +76,15 @@ def find_window(app: Application, waiting_time=10000, **selectors) -> WindowSpec
6276
return None
6377

6478

65-
def find_element(app: Application, from_parent_window: WindowSpecification = None,
79+
def find_element(app: Union[Application, WindowSpecification],
80+
from_parent_window: WindowSpecification = None,
6681
waiting_time=10000, **selectors) -> WindowSpecification:
6782
"""
6883
Find a element of the currently connected application using the available selectors.
6984
You can pass the context window where the element is contained.
7085
7186
Args:
72-
app (Application): The connected application.
87+
app (Application | WindowSpecification): The connected application.
7388
from_parent_window (WindowSpecification, optional): The element's parent window.
7489
waiting_time (int, optional): Maximum wait time (ms) to search for a hit.
7590
Defaults to 10000ms (10s).

botcity/core/bot.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,22 +97,22 @@ def __init__(self):
9797
self._mouse_controller = MouseController()
9898

9999
@property
100-
def app(self):
100+
def app(self) -> Union['Application', 'WindowSpecification']:
101101
"""
102102
The connected application instance to be used.
103103
104104
Returns:
105-
app (Application): The connected Application instance.
105+
app (Application | WindowSpecification): The connected Application/Window instance.
106106
"""
107107
return self._app
108108

109109
@app.setter
110-
def app(self, app):
110+
def app(self, app: Union['Application', 'WindowSpecification']):
111111
"""
112112
The connected application instance to be used.
113113
114114
Args:
115-
app (Application): The connected application to be used.
115+
app (Application | WindowSpecification): The connected Application/Window instance.
116116
"""
117117
self._app = app
118118

@@ -1608,7 +1608,8 @@ def sleep(self, interval):
16081608
#############
16091609

16101610
@if_windows_os
1611-
def connect_to_app(self, backend=Backend.WIN_32, timeout=60000, **connection_selectors) -> 'Application':
1611+
def connect_to_app(self, backend=Backend.WIN_32, timeout=60000,
1612+
**connection_selectors) -> Union['Application', 'WindowSpecification']:
16121613
"""
16131614
Connects to an instance of an open application.
16141615
Use this method to be able to access application windows and elements.
@@ -1623,7 +1624,7 @@ def connect_to_app(self, backend=Backend.WIN_32, timeout=60000, **connection_sel
16231624
](https://documentation.botcity.dev/frameworks/desktop/windows-apps/).
16241625
16251626
Returns
1626-
app (Application): The Application instance.
1627+
app (Application | WindowSpecification): The Application/Window instance.
16271628
"""
16281629
self.app = connect(backend, timeout, **connection_selectors)
16291630
return self.app

0 commit comments

Comments
 (0)