sugar-toolkit-gtk3/src/sugar3/test/uitree.py
Daniel Narvaez 4dc7b9e4a4 Don't set atspi timeout
Looking at the code I'm unconvinced this behaves as expected,
in certain cases at least. So reverting it for now to avoid
confusion.
2013-06-15 19:16:59 +02:00

172 lines
4.8 KiB
Python

# Copyright (C) 2012, Daniel Narvaez
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
"""
UNSTABLE.
"""
import logging
import time
from gi.repository import Atspi
from gi.repository import GLib
def get_root():
return Node(Atspi.get_desktop(0))
def _retry_find(func):
def wrapped(*args, **kwargs):
result = None
n_retries = 1
while n_retries <= 50:
logging.info("Try %d, name=%s role_name=%s" %
(n_retries,
kwargs.get("name", None),
kwargs.get("role_name", None)))
try:
result = func(*args, **kwargs)
except GLib.GError, e:
# The application is not responding, try again
if e.code == Atspi.Error.IPC:
continue
logging.error("GError code %d", e.code)
raise
expect_none = kwargs.get("expect_none", False)
if (not expect_none and result) or \
(expect_none and not result):
return result
time.sleep(1)
n_retries = n_retries + 1
return result
return wrapped
class Node:
def __init__(self, accessible):
self._accessible = accessible
def dump(self):
lines = []
self._crawl_accessible(self, 0, lines)
return "\n".join(lines)
def do_action(self, name):
for i in range(self._accessible.get_n_actions()):
# New, incompatible API
if hasattr(self._accessible, "get_action_name"):
action_name = self._accessible.get_action_name(i)
else:
action_name = Atspi.Action.get_name(self._accessible, i)
if action_name == name:
self._accessible.do_action(i)
def click(self, button=1):
point = self._accessible.get_position(Atspi.CoordType.SCREEN)
Atspi.generate_mouse_event(point.x, point.y, "b%sc" % button)
@property
def name(self):
return self._accessible.get_name()
@property
def role_name(self):
return self._accessible.get_role_name()
@property
def text(self):
return Atspi.Text.get_text(self._accessible, 0, -1)
def get_children(self):
children = []
for i in range(self._accessible.get_child_count()):
child = self._accessible.get_child_at_index(i)
# We sometimes get none children from atspi
if child is not None:
children.append(Node(child))
return children
@_retry_find
def find_children(self, name=None, role_name=None):
def predicate(node):
return self._predicate(node, name, role_name)
descendants = []
self._find_all_descendants(self, predicate, descendants)
if not descendants:
return []
return descendants
@_retry_find
def find_child(self, name=None, role_name=None, expect_none=False):
def predicate(node):
return self._predicate(node, name, role_name)
node = self._find_descendant(self, predicate)
if node is None:
return None
return node
def __str__(self):
return "[%s | %s]" % (self.name, self.role_name)
def _predicate(self, node, name, role_name):
if name is not None and name != node.name:
return False
if role_name is not None and role_name != node.role_name:
return False
return True
def _find_descendant(self, node, predicate):
if predicate(node):
return node
for child in node.get_children():
descendant = self._find_descendant(child, predicate)
if descendant is not None:
return descendant
return None
def _find_all_descendants(self, node, predicate, matches):
if predicate(node):
matches.append(node)
for child in node.get_children():
self._find_all_descendants(child, predicate, matches)
def _crawl_accessible(self, node, depth, lines):
lines.append(" " * depth + str(node))
for child in node.get_children():
self._crawl_accessible(child, depth + 1, lines)