Skip to content

Commit 18d68e2

Browse files
committed
Collect tree to save the context
1 parent 47c504a commit 18d68e2

4 files changed

Lines changed: 58 additions & 10 deletions

File tree

robocorp-code/src/robocorp_code/inspector/java/java_inspector.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"y": int,
3131
"width": int,
3232
"height": int,
33+
"ancestry": int,
3334
},
3435
)
3536

@@ -53,7 +54,10 @@ def to_window_info(java_window: JavaWindow) -> JavaWindowInfoTypedDict:
5354
def to_locator_info(context_node: ContextNode) -> LocatorNodeInfoTypedDict:
5455
ret = {}
5556
for dct_name in LocatorNodeInfoTypedDict.__annotations__:
56-
ret[dct_name] = getattr(context_node.context_info, dct_name)
57+
if (dct_name) == "ancestry":
58+
ret["ancestry"] = getattr(context_node, dct_name)
59+
else:
60+
ret[dct_name] = getattr(context_node.context_info, dct_name)
5761
return cast(LocatorNodeInfoTypedDict, ret)
5862

5963

@@ -82,7 +86,7 @@ def list_windows(self) -> List[JavaWindowInfoTypedDict]:
8286
return [to_window_info(window) for window in windows]
8387

8488
def collect_tree(
85-
self, window: str, search_depth: int = 8, locator: Optional[str] = None
89+
self, window: str, search_depth=1, locator: Optional[str] = None
8690
) -> MatchesAndHierarchyTypedDict:
8791
log.info(f"Collect tree from locator: {locator}")
8892

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class NoMatchingLocatorException(Exception):
2+
"""Match for locator not found."""

robocorp-code/src/robocorp_code/inspector/java/robocorp_java/_inspector.py

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313

1414

1515
class ElementInspector:
16+
def __init__(self) -> None:
17+
self._context: Optional[ContextNode] = None
18+
1619
def _start_event_pump(func, *args, **kwargs):
1720
def wrapper(self: "ElementInspector", *args, **kwargs):
1821
from ._event_pump import EventPumpThread
@@ -32,6 +35,47 @@ def wrapper(self: "ElementInspector", *args, **kwargs):
3235
def list_windows(self, jab_wrapper: JavaAccessBridgeWrapper) -> List[JavaWindow]:
3336
return jab_wrapper.get_windows()
3437

38+
def _collect_from_root(
39+
self,
40+
jab_wrapper: JavaAccessBridgeWrapper,
41+
locator: Optional[str],
42+
search_depth=1,
43+
) -> ColletedTreeTypedDict:
44+
self._context = ContextTree(jab_wrapper, search_depth).root
45+
matches: Union[ContextNode, List[ContextNode]] = []
46+
if locator:
47+
from ._locators import find_elements_from_tree
48+
49+
matches = find_elements_from_tree(self._context, locator)
50+
return {"matches": matches, "tree": self._context}
51+
52+
def _collect_from_context(
53+
self, jab_wrapper: JavaAccessBridgeWrapper, locator: str, search_depth=1
54+
) -> ColletedTreeTypedDict:
55+
from threading import RLock
56+
57+
from ._errors import NoMatchingLocatorException
58+
from ._locators import find_elements_from_tree
59+
60+
# The JavaAccessBridgeWrapper object needs to be inserted into the context as the
61+
# object has to be recreated every time we do a new query
62+
# TODO: update the ContextTree to introduce the API for this
63+
self._context._jab_wrapper = jab_wrapper
64+
match = find_elements_from_tree(self._context, locator)
65+
node = match[0] if isinstance(match, List) and len(match) > 0 else match
66+
if not isinstance(node, ContextNode):
67+
raise NoMatchingLocatorException(f"No matching locator for {locator}")
68+
self._context = ContextNode(
69+
jab_wrapper,
70+
node.context,
71+
RLock(),
72+
node.ancestry,
73+
True,
74+
search_depth + node.ancestry,
75+
)
76+
matches = find_elements_from_tree(self._context, locator)
77+
return {"matches": matches, "tree": self._context}
78+
3579
@_start_event_pump
3680
def collect_tree(
3781
self,
@@ -41,10 +85,8 @@ def collect_tree(
4185
locator: Optional[str] = None,
4286
) -> ColletedTreeTypedDict:
4387
jab_wrapper.switch_window_by_title(window)
44-
context_tree = ContextTree(jab_wrapper, search_depth)
45-
matches: Union[ContextNode, List[ContextNode]] = []
46-
if locator:
47-
from ._locators import find_elements_from_tree
4888

49-
matches = find_elements_from_tree(context_tree, locator)
50-
return {"matches": matches, "tree": context_tree.root}
89+
if not self._context:
90+
return self._collect_from_root(jab_wrapper, locator, search_depth)
91+
else:
92+
return self._collect_from_context(jab_wrapper, locator, search_depth)

robocorp-code/src/robocorp_code/inspector/java/robocorp_java/_locators.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ def _parse_locator(locator: str, strict_default=False):
2222
conditions = lvl.split(" and ")
2323
lvl_search = []
2424
strict_mode = strict_default
25-
for cond in conditions:
26-
parts = cond.split(":", 1)
25+
for condition in conditions:
26+
parts = condition.split(":", 1)
2727
if len(parts) == 1:
2828
parts = ["name", parts[0]]
2929
elif parts[0].lower() == "strict":

0 commit comments

Comments
 (0)