def connect(self, file): ''' Loads an accessible tree from the given file. :param file: A name of the XML file to load :type file: string ''' def setPath(acc, parentPath=None): if parentPath is None: acc.path = Path() else: acc.path = parentPath.child(acc.index) for child in acc.children(): setPath(child, acc.path) try: element = etree.ElementTree(file=file).getroot() acc = Accessible.unmarshal(element) if not acc.path.tuple: self._root = acc else: self._root = Accessible(Path(), children=(acc, )) acc.index = 0 setPath(self._root) except Exception, err: self.messages.put(Error(err))
def setPath(acc, parentPath=None): if parentPath is None: acc.path = Path() else: acc.path = parentPath.child(acc.index) for child in acc.children(): setPath(child, acc.path)
def testExecActionA11yRequest(self): params = {"path": Path(0, 1, 2, 3), "action": u"TestAction"} req = protocol.create(protocol.MSG_TYPE_REQUEST, protocol.MSG_TARGET_ACCESSIBILITY, protocol.MSG_NAME_EXEC, **params) self.failUnless(isinstance(req, message.Request)) cls = type(req) req = protocol.parse(req.marshal()) self.failUnless(isinstance(req, cls)) for name in params: self.failUnlessEqual(getattr(req, name), params[name])
def testSearchA11yResponse(self): accessible = Accessible(Path(0, 1, 2, 3)) res = protocol.create(protocol.MSG_TYPE_RESPONSE, protocol.MSG_TARGET_ACCESSIBILITY, protocol.MSG_NAME_SEARCH, accessible=accessible, status=True) self.failUnless(isinstance(res, message.Response)) cls = type(res) res = protocol.parse(res.marshal()) self.failUnless(isinstance(res, cls)) self.failUnlessEqual(res.accessible.path, accessible.path) self.failUnlessEqual(res.status, True)
def testExecKeyboardA11yRequest(self): params = { "path": Path(0, 1, 2, 3), "keycode": 123, "modifiers": (234, 345, 456) } req = protocol.create(protocol.MSG_TYPE_REQUEST, protocol.MSG_TARGET_ACCESSIBILITY, protocol.MSG_NAME_EXEC, **params) self.failUnless(isinstance(req, message.Request)) cls = type(req) req = protocol.parse(req.marshal()) self.failUnless(isinstance(req, cls)) for name in params: self.failUnlessEqual(getattr(req, name), params[name])
def testGetA11yRequest(self): params = { "path": Path(0, 1, 2, 3), "depth": 3, "include": (u"name", u"role", u"count", u"text") } req = protocol.create(protocol.MSG_TYPE_REQUEST, protocol.MSG_TARGET_ACCESSIBILITY, protocol.MSG_NAME_GET, **params) self.failUnless(isinstance(req, message.Request)) cls = type(req) req = protocol.parse(req.marshal()) self.failUnless(isinstance(req, cls)) for name in params: self.failUnlessEqual(getattr(req, name), params[name])
def testExecMouseA11yRequest(self): params = { "path": Path(0, 1, 2, 3), "button": u"TestButton", "event": u"TestEvent", "coordinates": (1024, 800) } req = protocol.create(protocol.MSG_TYPE_REQUEST, protocol.MSG_TARGET_ACCESSIBILITY, protocol.MSG_NAME_EXEC, **params) self.failUnless(isinstance(req, message.Request)) cls = type(req) req = protocol.parse(req.marshal()) self.failUnless(isinstance(req, cls)) for name in params: self.failUnlessEqual(getattr(req, name), params[name])
def testSearchA11yRequest(self): params = { "path": Path(0, 1, 2, 3), "method": protocol.MHD_SEARCH_SIMPLE, "predicates": { "name": u"TestName", "role": u"TestRole", "count": 3, "text": u"TestText" } } req = protocol.create(protocol.MSG_TYPE_REQUEST, protocol.MSG_TARGET_ACCESSIBILITY, protocol.MSG_NAME_SEARCH, **params) self.failUnless(isinstance(req, message.Request)) cls = type(req) req = protocol.parse(req.marshal()) self.failUnless(isinstance(req, cls)) for name in params: self.failUnlessEqual(getattr(req, name), params[name])
def accessibilitySearch(processor, path, method, name=None, description=None, role=None, index=None, count=None, action=None, relation=None, state=None, text=None, nth=0): ''' Searches an accessible using the given method according to specified accessible parameters. :param processor: A processor object calling the function :type processor: Processor :param path: A path of a demanded accessible :type path: tadek.core.accessible.Path :param method: A search method of accessible :type method: string :param name: A name of searched accessible or None :type name: string or NoneType :param description: A description of searched accessible or None :type description: string or NoneType :param role: A role of searched accessible or None :type role: string or NoneType :param index: An index of searched accessible or None :type index: integer or NoneType :param count: A child count of searched accessible or None :type count: string or NoneType :param action: An action of searched accessible or None :type action: string or NoneType :param relation: A relation of searched accessible or None :type relation: string or NoneType :param state: A state of searched accessible or None :type state: string or NoneType :param text: Text of searched accessible or None :type text: string or NoneType :param nth: A nth matched accessible :type nth: integer :return: A searching accessible status and an accessible of the given path :rtype: tuple ''' log.debug(str(locals())) def matchString(pattern, string): ''' Checks if the give string matches the regular expression pattern. ''' if string is None: return False match = pattern.match(string) return match is not None and match.span() == (0, len(string)) try: # Get object from the processor cache or from the accessible provider if processor.cache and processor.cache[-1] == path: a11y, obj, path = processor.cache else: a11y, obj = providers.accessible(path) # Reset the processor cache processor.cache = None if a11y is None and path.tuple: log.info("Accessible of requested path not found: %s" % path) return False, Accessible(path) if method == protocol.MHD_SEARCH_SIMPLE: provider = providers.Children elif method == protocol.MHD_SEARCH_BACKWARDS: provider = providers.ChildrenBackwards elif method == protocol.MHD_SEARCH_DEEP: provider = providers.Descendants else: log.error("Unknown search method: %s" % method) return False, Accessible(Path()) if name and name[0] == '&': name = re.compile(name[1:], re.DOTALL) cmpName = matchString else: cmpName = lambda pattern, string: pattern == string if description and description[0] == '&': description = re.compile(description[1:], re.DOTALL) cmpDesc = matchString else: cmpDesc = lambda pattern, string: pattern == string if text and text[0] == '&': text = re.compile(text[1:], re.DOTALL) cmpText = matchString else: cmpText = lambda pattern, string: pattern == string i = 0 for a11y, obj, path in provider(a11y, obj, path): if index is not None and index != path.index(): continue if obj is None: if name is not None and not cmpName(name, a11y.name): continue if count is not None and a11y.countChildren() != count: continue else: if name is not None and not cmpName(name, a11y.getName(obj)): continue if (description is not None and not cmpDesc(description, a11y.getDescription(obj))): continue if role is not None and a11y.getRoleName(obj) != role: continue if count is not None and a11y.countChildren(obj) != count: continue if action is not None: found = False for act in a11y.actionNames(obj): if action == act: found = True break if not found: continue if relation is not None: found = False for rel in a11y.relationNames(obj): if relation == rel: found = True break if not found: continue if (state is not None and not a11y.inState( obj, getattr(a11y.stateset, state, None))): continue if text is not None and not cmpText(text, a11y.getText(obj)): continue i += 1 if nth < i: processor.cache = (a11y, obj, path) return True, dumpAccessible(a11y, obj, path, depth=0, name=True, description=True, role=True, count=True, position=True, size=True, text=True, value=True, actions=True, states=True, attributes=True, relations=True) except: log.exception("Search an accessible of specified parmaters error") # Reset the processor cache before leaving processor.cache = None return False, Accessible(path) log.info("Search an accessible of specified parmaters failure") return False, Accessible(path)
def dumpAccessible(a11y, obj, path, depth, name, description, role, count, position, size, text, value, actions, states, attributes, relations): ''' Dumps the given accessible object and returns it as an Accessible instance. :param a11y: An accessibility releated to a given accessible object :type a11y: ModuleType :param obj: An accessible object to dump :type obj: accessible :param path: A path of a given accessible object :type path: tadek.core.accessible.Path :param depth: A depth of the dump :type depth: integer :param name: True if the dump should include accessible name :type name: boolean :param description: True if the dump should include accessible description :type description: boolean :param role: True if the dump should include accessible role :type role: boolean :param count: True if the dump should include number of accessible children :type count: boolean :param position: True if the dump should include accessible position :type position: boolean :param size: True if the dump should include accessible size :type size: boolean :param text: True if the dump should include accessible text :type text: boolean :param value: True if the dump should include accessible value :type value: boolean :param actions: True if the dump should include accessible actions :type actions: boolean :param states: True if the dump should include accessible states :type states: boolean :param attributes: True if the dump should include accessible attributes :type attributes: boolean :param relations: True if the dump should include accessible relations :type relations: bool :return: A dumped accessible object :rtype: tadek.core.accessible.Accessible ''' log.debug(str(locals())) def getPath(a11y, obj, path): ''' Gets a path of the given accessible object. ''' # Insert indexes of accessibility and application of the object path = [path.tuple[0], path.tuple[1]] while obj is not None: path.insert(2, a11y.getIndex(obj)) obj = a11y.getParent(obj) return path if obj is None and len(path.tuple) > 1: # Invalid accessible object return Accessible(path) try: children = [] if depth != 0: for a, o, p in providers.Children(a11y, obj, path): children.append( dumpAccessible(a, o, p, depth - 1, name, description, role, count, position, size, text, value, actions, states, attributes, relations)) acc = Accessible(path, children) if a11y is None: if count: acc.count = providers.a11yCount elif obj is None: # Accessibility might have only name and numer of children if name: acc.name = a11y.name if count: acc.count = a11y.countChildren() else: if name: acc.name = a11y.getName(obj) if description: acc.description = a11y.getDescription(obj) if role: acc.role = a11y.getRoleName(obj) if count: acc.count = a11y.countChildren(obj) if position: acc.position = a11y.getPosition(obj) if size: acc.size = a11y.getSize(obj) if text: acc.text = a11y.getText(obj) acc.editable = a11y.inState(obj, a11y.stateset.EDITABLE) if value: acc.value = a11y.getValue(obj) if actions: acc.actions = [a for a in a11y.actionNames(obj)] if a11y.inState(obj, a11y.stateset.FOCUSABLE): acc.actions.insert(0, A11Y_ACTION_FOCUS) if states: acc.states = [ a11y.stateset.name(s) for s in a11y.states(obj) if a11y.stateset.name(s) is not None ] if attributes: acc.attributes = a11y.getAttributes(obj) if relations: for relation in a11y.relations(obj): name = a11y.relationset.name(relation) if name: targets = [ Path(*getPath(a11y, t, path)) for t in a11y.relationTargets(obj, relation) ] acc.relations.append(Relation(name, targets)) except: log.exception("Dumping accessible object error: %s" % path) acc = Accessible(path) return acc
if i != idx: return None except Exception, err: self.messages.put(Error(err)) acc = None return acc extras = {} if self._root is None: self.messages.put(Error("XML client is not connected")) elif request.target == protocol.MSG_TARGET_ACCESSIBILITY: if request.name == protocol.MSG_NAME_GET: accessible = getAccessible(request.path) extras = { "status": accessible is not None, "accessible": accessible or Accessible(Path()) } elif request.name == protocol.MSG_NAME_SEARCH: acc = getAccessible(request.path) # TODO: Currently not used elif request.name == protocol.MSG_NAME_PUT: extras = {"status": False} elif request.name == protocol.MSG_NAME_EXEC: extras = {"status": False} elif request.target == protocol.MSG_TARGET_SYSTEM: if request.name == protocol.MSG_NAME_GET: extras = {"status": False, "data": ''} elif request.name == protocol.MSG_NAME_PUT: extras = {"status": False} elif request.name == protocol.MSG_NAME_EXEC: extras = {"status": False, "stdout": '', "stderr": ''}