~ubuntu-branches/debian/sid/sugar-toolkit-gtk3/sid

« back to all changes in this revision

Viewing changes to src/sugar3/test/uitree.py

  • Committer: Package Import Robot
  • Author(s): Jonas Smedegaard
  • Date: 2015-04-17 10:34:39 UTC
  • mfrom: (4.1.4 experimental)
  • Revision ID: package-import@ubuntu.com-20150417103439-xsqh30o8p0v6bflp
Tags: 0.104.1-5
* Move packaging to Debian Sugar Team.
* Update package relations:
  + Fix depend on python-gi-cairo.
    Thanks to Martin Abente and James Cameron.
* Fix typo in libsugarext-dev short description.
  Closes: bug#747026. Thanks to Anders Jonsson.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2012, Daniel Narvaez
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
16
 
 
17
"""
 
18
UNSTABLE.
 
19
"""
 
20
 
 
21
import logging
 
22
import time
 
23
 
 
24
from gi.repository import Atspi
 
25
from gi.repository import GLib
 
26
 
 
27
 
 
28
def get_root():
 
29
    return Node(Atspi.get_desktop(0))
 
30
 
 
31
 
 
32
def _retry_find(func):
 
33
    def wrapped(*args, **kwargs):
 
34
        result = None
 
35
        n_retries = 1
 
36
 
 
37
        while n_retries <= 50:
 
38
            logging.info("Try %d, name=%s role_name=%s" %
 
39
                         (n_retries,
 
40
                          kwargs.get("name", None),
 
41
                          kwargs.get("role_name", None)))
 
42
 
 
43
            try:
 
44
                result = func(*args, **kwargs)
 
45
            except GLib.GError, e:
 
46
                # The application is not responding, try again
 
47
                if e.code == Atspi.Error.IPC:
 
48
                    continue
 
49
 
 
50
                logging.error("GError code %d" % e.code)
 
51
                raise
 
52
 
 
53
            expect_none = kwargs.get("expect_none", False)
 
54
            if (not expect_none and result) or \
 
55
               (expect_none and not result):
 
56
                return result
 
57
 
 
58
            time.sleep(1)
 
59
            n_retries = n_retries + 1
 
60
 
 
61
        return result
 
62
 
 
63
    return wrapped
 
64
 
 
65
 
 
66
class Node:
 
67
    def __init__(self, accessible):
 
68
        self._accessible = accessible
 
69
 
 
70
    def dump(self):
 
71
        lines = []
 
72
        self._crawl_accessible(self, 0, lines)
 
73
        return "\n".join(lines)
 
74
 
 
75
    def do_action(self, name):
 
76
        for i in range(self._accessible.get_n_actions()):
 
77
            # New, incompatible API
 
78
            if hasattr(self._accessible, "get_action_name"):
 
79
                action_name = self._accessible.get_action_name(i)
 
80
            else:
 
81
                action_name = Atspi.Action.get_name(self._accessible, i)
 
82
 
 
83
            if action_name == name:
 
84
                self._accessible.do_action(i)
 
85
 
 
86
    def click(self, button=1):
 
87
        point = self._accessible.get_position(Atspi.CoordType.SCREEN)
 
88
        Atspi.generate_mouse_event(point.x, point.y, "b%sc" % button)
 
89
 
 
90
    @property
 
91
    def name(self):
 
92
        return self._accessible.get_name()
 
93
 
 
94
    @property
 
95
    def role_name(self):
 
96
        return self._accessible.get_role_name()
 
97
 
 
98
    @property
 
99
    def text(self):
 
100
        return Atspi.Text.get_text(self._accessible, 0, -1)
 
101
 
 
102
    def get_children(self):
 
103
        children = []
 
104
 
 
105
        for i in range(self._accessible.get_child_count()):
 
106
            child = self._accessible.get_child_at_index(i)
 
107
 
 
108
            # We sometimes get none children from atspi
 
109
            if child is not None:
 
110
                children.append(Node(child))
 
111
 
 
112
        return children
 
113
 
 
114
    @_retry_find
 
115
    def find_children(self, name=None, role_name=None):
 
116
        def predicate(node):
 
117
            return self._predicate(node, name, role_name)
 
118
 
 
119
        descendants = []
 
120
        self._find_all_descendants(self, predicate, descendants)
 
121
        if not descendants:
 
122
            return []
 
123
 
 
124
        return descendants
 
125
 
 
126
    @_retry_find
 
127
    def find_child(self, name=None, role_name=None, expect_none=False):
 
128
        def predicate(node):
 
129
            return self._predicate(node, name, role_name)
 
130
 
 
131
        node = self._find_descendant(self, predicate)
 
132
        if node is None:
 
133
            return None
 
134
 
 
135
        return node
 
136
 
 
137
    def __str__(self):
 
138
        return "[%s | %s]" % (self.name, self.role_name)
 
139
 
 
140
    def _predicate(self, node, name, role_name):
 
141
        if name is not None and name != node.name:
 
142
            return False
 
143
 
 
144
        if role_name is not None and role_name != node.role_name:
 
145
            return False
 
146
 
 
147
        return True
 
148
 
 
149
    def _find_descendant(self, node, predicate):
 
150
        if predicate(node):
 
151
            return node
 
152
 
 
153
        for child in node.get_children():
 
154
            descendant = self._find_descendant(child, predicate)
 
155
            if descendant is not None:
 
156
                return descendant
 
157
 
 
158
        return None
 
159
 
 
160
    def _find_all_descendants(self, node, predicate, matches):
 
161
        if predicate(node):
 
162
            matches.append(node)
 
163
 
 
164
        for child in node.get_children():
 
165
            self._find_all_descendants(child, predicate, matches)
 
166
 
 
167
    def _crawl_accessible(self, node, depth, lines):
 
168
        lines.append("  " * depth + str(node))
 
169
 
 
170
        for child in node.get_children():
 
171
            self._crawl_accessible(child, depth + 1, lines)