Skip to content

Commit

Permalink
Make kato use window_hierarchy_to_selector_list
Browse files Browse the repository at this point in the history
  • Loading branch information
dtmilano committed Nov 8, 2022
1 parent be809aa commit 1201a5c
Show file tree
Hide file tree
Showing 4 changed files with 275 additions and 183 deletions.
Binary file modified docs/.doctrees/environment.pickle
Binary file not shown.
45 changes: 33 additions & 12 deletions src/com/dtmilano/android/kato/kato.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,38 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2012-2022 Diego Torres Milano
Created on Nov 7, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@author: Diego Torres Milano
"""

import sys
from collections import OrderedDict

from culebratester_client import Selector
from culebratester_client.rest import ApiException

from com.dtmilano.android.distance import levenshtein_distance
from com.dtmilano.android.uiautomator.utils import window_hierarchy_to_selector_list

#
# https://en.wikipedia.org/wiki/Kato_(The_Green_Hornet)
#

DEBUG = False

ANYTHING = 'Pattern:^.*$'


class Kato:
def __init__(self):
Expand All @@ -25,11 +44,13 @@ def __init__(self):
def kato(func):
"""
Kato decorator.
@param func:the function to invoke
@type func:
@return: the wrapper
@rtype:
:param func: the function to invoke
:type func: function
:return: the wrapper
:rtype:
"""

def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
Expand Down Expand Up @@ -57,18 +78,18 @@ def find_me_the_selectors(e: ApiException, *args, **kwargs):
print('find_me_the_selectors', args, kwargs, file=sys.stderr)
helper = args[0].uiAutomatorHelper
msg = ''
_d = dict()
if helper.kato.enabled:
if e.status == 404:
distance = kwargs['distance_func']
mapper = kwargs['distance_func_argument_mapper']
helper.kato.selectors = list(map(lambda oid: helper.ui_object2.dump(oid),
map(lambda obj_ref: obj_ref.oid,
helper.ui_device.find_objects(body={'text': ANYTHING}))))
for n, s in enumerate(filter(lambda _s: helper.ui_device.has_object(body=_s), helper.kato.selectors)):
selector = Selector(**kwargs['body'])
helper.kato.selectors = window_hierarchy_to_selector_list(
helper.ui_device.dump_window_hierarchy(_format='JSON'))
_d = dict()
for n, s in enumerate(helper.kato.selectors):
if n == 0:
msg += 'Kato: selector distances:\n'
d = distance(mapper(Selector(**kwargs['body'])), mapper(s))
d = distance(mapper(selector), mapper(s))
_d[d] = s
msg += f'{d} -> {s}\n'
helper.kato.distances = OrderedDict(sorted(_d.items(), reverse=False))
Expand Down
71 changes: 71 additions & 0 deletions src/com/dtmilano/android/uiautomator/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2012-2022 Diego Torres Milano
Created on Nov 7, 2022
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
@author: Diego Torres Milano
"""

from __future__ import print_function

from typing import Union

from culebratester_client import WindowHierarchyChild, Selector, WindowHierarchy


def window_hierarchy_child_to_selector(window_hierarchy_child: WindowHierarchyChild) -> Selector:
"""
Converts a WindowHierarchyChild to a Selector.
:param window_hierarchy_child: the WindowHierarchyChild to convert
:type window_hierarchy_child: WindowHierarchyChild
:return: the Selector
:rtype: Selector
"""
sel = Selector()
sel.checkable = window_hierarchy_child.checkable
sel.checked = window_hierarchy_child.checked
sel.clazz = window_hierarchy_child.clazz
sel.clickable = window_hierarchy_child.clickable
sel.depth = None
sel.desc = window_hierarchy_child.content_description if window_hierarchy_child.content_description else None
sel.pkg = window_hierarchy_child.package if window_hierarchy_child.package else None
sel.res = window_hierarchy_child.resource_id if window_hierarchy_child.resource_id else None
sel.scrollable = window_hierarchy_child.scrollable
sel.text = window_hierarchy_child.text if window_hierarchy_child.text else None
sel.index = None # child.index (could be 0)
sel.instance = None
return sel


def window_hierarchy_to_selector_list(node: Union[WindowHierarchy, WindowHierarchyChild], selector_list=None) -> list[
Selector]:
"""
Converts a WindowHierarchy (obtained via ``window_hierarchy_dump()``) to a Selector list.
:param node: the node being processed
:type node: Union[WindowHierarchy, WindowHierarchyChild]
:param selector_list: the list, could be ``None``
:type selector_list: list[Selector]
:return: the list
:rtype: list[Selector]
"""
if selector_list is None:
selector_list = []
if node.id != 'hierarchy':
selector_list.append(window_hierarchy_child_to_selector(node))
for ch in node.children:
window_hierarchy_to_selector_list(ch, selector_list)
return selector_list
Loading

0 comments on commit 1201a5c

Please sign in to comment.