summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEitan Isaacson <eitan@ascender.com>2009-08-31 11:53:09 -0700
committerEitan Isaacson <eitan@ascender.com>2009-08-31 11:53:09 -0700
commit6e99dbe2d4b9e385b5347cc9d3106413603ca6b5 (patch)
treec3011200c7c6143968d3d8653d79fb8f584b8bed
parent18ec505eea6240f468778eaff0ce6a4b7e0637ad (diff)
parent128778a78635f2da62c0df1107b7b721a74ae569 (diff)
Merge branch 'master' into lazy_loaderlazy_loader
-rw-r--r--ChangeLog42
-rw-r--r--INSTALL291
-rw-r--r--Makefile.am7
-rw-r--r--NEWS0
-rw-r--r--README0
-rwxr-xr-xautogen.sh5
-rw-r--r--configure.in51
-rwxr-xr-xfind-python-path.py17
-rw-r--r--ldtp/Makefile.am21
-rw-r--r--ldtp/__init__.py8
-rw-r--r--ldtpd/Makefile.am34
-rw-r--r--ldtpd/combo_box.py107
-rw-r--r--ldtpd/core.py62
-rw-r--r--ldtpd/generic.py12
-rw-r--r--ldtpd/menu.py80
-rw-r--r--ldtpd/page_tab_list.py25
-rw-r--r--ldtpd/table.py44
-rw-r--r--ldtpd/text.py36
-rw-r--r--ldtpd/utils.py23
-rw-r--r--ldtpd/value.py64
-rw-r--r--ldtputils/Makefile.am17
-rw-r--r--ooldtp/Makefile.am18
22 files changed, 817 insertions, 147 deletions
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..588cbfc
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,42 @@
+2009-08-25 Nagappan Alagappan <nagappan@gmail.com>
+
+ * ldtpd/value.py (Value.verifyslidervertical): Return 0 on
+ failure.
+
+ * ldtpd/utils.py (Utils._match_name_to_acc): Added new condition,
+ which will check for the object name, by stripping all spaces.
+ (Utils._appmap_pairs): Increment object index to each specific
+ type and use that when the object doesn't have any associated
+ label.
+ (Utils._get_menu_hierarchy): Fix, fetching the child of a menu.
+
+ * ldtpd/text.py (Text.gettextvalue): Added additional parameters
+ to reflect LDTPv1 arguments.
+ (Text.verifypartialmatch): Return 0 on failure.
+
+ * ldtpd/table.py (Table.verifytablecell): Return 0 on failure.
+
+ * ldtpd/page_tab_list.py (PageTabList.verifytabname): Return 0 on
+ failure, instead of raising exception.
+
+ * ldtpd/menu.py (Menu.menuitemenabled, Menu.verifymenucheck):
+ (Menu.verifymenuuncheck): Added new method to reflect LDTPv1.
+
+ * ldtpd/generic.py (Generic.imagecapture): Updated arguments to
+ reflect the latest LDTPv1.
+
+ * ldtpd/core.py (Ldtpd.launchapp): Added arguments, same as
+ LDTPv1.
+ (Ldtpd.verifytoggled): Added try/except block, to avoid any
+ exception. This method has to either return 1 or 0.
+ (Ldtpd.getobjectinfo): Added new properties.
+
+ * ldtpd/combo_box.py (ComboBox.verifydropdown): Added try/except
+ block, to avoid any exception. This method has to either return 1
+ or 0.
+
+ * configure.in: Added makefile and related files.
+
+ * ldtp/__init__.py (imagecapture): Updated arguments to reflect
+ the latest LDTPv1.
+
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..8b82ade
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,291 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
+2006, 2007, 2008 Free Software Foundation, Inc.
+
+ This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+ Briefly, the shell commands `./configure; make; make install' should
+configure, build, and install this package. The following
+more-detailed instructions are generic; see the `README' file for
+instructions specific to this package.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+ It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring. Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+ The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'. You need `configure.ac' if
+you want to change it or regenerate `configure' using a newer version
+of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system.
+
+ Running `configure' might take a while. While running, it prints
+ some messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+ 6. Often, you can also type `make uninstall' to remove the installed
+ files again.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+ You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment. Here
+is an example:
+
+ ./configure CC=c99 CFLAGS=-g LIBS=-lposix
+
+ *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you can use GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ With a non-GNU `make', it is safer to compile the package for one
+architecture at a time in the source code directory. After you have
+installed the package for one architecture, use `make distclean' before
+reconfiguring for another architecture.
+
+ On MacOS X 10.5 and later systems, you can create libraries and
+executables that work on multiple system types--known as "fat" or
+"universal" binaries--by specifying multiple `-arch' options to the
+compiler but only a single `-arch' option to the preprocessor. Like
+this:
+
+ ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+ CPP="gcc -E" CXXCPP="g++ -E"
+
+ This is not guaranteed to produce working output in all cases, you
+may have to build one architecture at a time and combine the results
+using the `lipo' tool if you have problems.
+
+Installation Names
+==================
+
+ By default, `make install' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Particular systems
+==================
+
+ On HP-UX, the default C compiler is not ANSI C compatible. If GNU
+CC is not installed, it is recommended to use the following options in
+order to use an ANSI C compiler:
+
+ ./configure CC="cc -Ae"
+
+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
+
+ On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
+parse its `<wchar.h>' header file. The option `-nodtk' can be used as
+a workaround. If GNU CC is not installed, it is therefore recommended
+to try
+
+ ./configure CC="cc"
+
+and if that doesn't work, try
+
+ ./configure CC="cc -nodtk"
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on. Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+ CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+ OS KERNEL-OS
+
+ See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+ If you are _building_ compiler tools for cross-compiling, you should
+use the option `--target=TYPE' to select the type of system they will
+produce code for.
+
+ If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+ Variables not defined in a site shell script can be set in the
+environment passed to `configure'. However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost. In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'. For example:
+
+ ./configure CC=/usr/local2/bin/gcc
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+Unfortunately, this technique does not work for `CONFIG_SHELL' due to
+an Autoconf bug. Until the bug is fixed you can use this workaround:
+
+ CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+`configure' Invocation
+======================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+ Print a summary of all of the options to `configure', and exit.
+
+`--help=short'
+`--help=recursive'
+ Print a summary of the options unique to this package's
+ `configure', and exit. The `short' variant lists options used
+ only in the top level, while the `recursive' variant lists options
+ also present in any nested packages.
+
+`--version'
+`-V'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`--cache-file=FILE'
+ Enable the cache: use and save the results of the tests in FILE,
+ traditionally `config.cache'. FILE defaults to `/dev/null' to
+ disable caching.
+
+`--config-cache'
+`-C'
+ Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--prefix=DIR'
+ Use DIR as the installation prefix. *Note Installation Names::
+ for more details, including other options available for fine-tuning
+ the installation locations.
+
+`--no-create'
+`-n'
+ Run the configure checks, but stop before creating any output
+ files.
+
+`configure' also accepts some other, not widely useful, options. Run
+`configure --help' for more details.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..78bafe4
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,7 @@
+PYTHONDIR = ldtp ooldtp ldtpd ldtputils
+
+SUBDIRS = $(PYTHONDIR)
+
+DIST_SUBDIRS = $(PYTHONDIR)
+
+EXTRA_DIST = find-python-path.py
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/NEWS
diff --git a/README b/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/README
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..1729c80
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+aclocal
+automake --add-missing; autoreconf -sfi -v
+./configure $@
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000..faeecb7
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,51 @@
+dnl *************************************************************
+dnl Process this file with autoconf to produce a configure script
+dnl *************************************************************
+AC_INIT(ldtp2, 2.0, ldtp-dev@lists.freedesktop.org)
+AC_CANONICAL_SYSTEM
+
+AM_INIT_AUTOMAKE
+
+AC_PREREQ(2.52)
+
+dnl checks for programs
+AC_PROG_INSTALL
+
+AC_PATH_PROG(PYTHON_CMD, python, no)
+if test "x$PYTHON_CMD" = "xno"; then
+ AC_MSG_ERROR([Your python installation doesn't expose python])
+fi
+
+dnl Check for the python site-packages install path
+dnl Copied over from a11y-test-suite
+AC_MSG_CHECKING([python site path])
+pythonsitedir="`./find-python-path.py`"
+pythondir="${pythonsitedir}"
+ldtpdir="${pythondir}/ldtp"
+ldtpddir="${pythondir}/ldtpd"
+ooldtpdir="${pythondir}/ooldtp"
+ldtputilsdir="${pythondir}/ldtputils"
+AC_MSG_RESULT([$ldtpdir])
+AC_MSG_RESULT([$ldtpddir])
+AC_MSG_RESULT([$ooldtpdir])
+AC_MSG_RESULT([$ldtputilsdir])
+AC_MSG_RESULT([$pythondir])
+AC_SUBST(ldtpdir)
+AC_SUBST(ldtpddir)
+AC_SUBST(ooldtpdir)
+AC_SUBST(ldtputilsdir)
+AC_SUBST(pythondir)
+
+AC_OUTPUT([
+ldtp/Makefile
+ooldtp/Makefile
+ldtpd/Makefile
+ldtputils/Makefile
+Makefile
+])
+
+echo "---"
+echo "Configuration successful."
+echo
+
+dnl configure.in ends here
diff --git a/find-python-path.py b/find-python-path.py
new file mode 100755
index 0000000..21a9d0b
--- /dev/null
+++ b/find-python-path.py
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+
+import sys
+from os.path import split, basename
+
+def find_path ():
+ for path in sys.path:
+ (head, tail) = split (path)
+ # Forcing python path to be used as /usr/lib instead of /usr/local/lib
+ if (tail == 'site-packages' or tail == 'dist-packages') and \
+ path.find ('local') == -1:
+ base = basename (head)
+ print path
+ #print base + '/' + tail
+ return
+
+find_path ()
diff --git a/ldtp/Makefile.am b/ldtp/Makefile.am
new file mode 100644
index 0000000..3273f21
--- /dev/null
+++ b/ldtp/Makefile.am
@@ -0,0 +1,21 @@
+ldtp_DATA = \
+ log.py \
+ state.py \
+ client_exception.py \
+ client.py \
+ __init__.py
+
+pyc_DATA = $(ldtp_DATA:.py=.pyc)
+pycdir = $(ldtpdir)
+
+%.pyc: %.py
+ $(PYTHON_CMD) -c "import py_compile; py_compile.compile ('$<', '$@')"
+
+EXTRA_DIST = \
+ $(ldtp_DATA)
+
+CLEANFILES = \
+ $(pyc_DATA)
+
+MAINTAINERCLEANFILES = \
+ Makefile.in
diff --git a/ldtp/__init__.py b/ldtp/__init__.py
index 4a72096..72d3bd2 100644
--- a/ldtp/__init__.py
+++ b/ldtp/__init__.py
@@ -45,12 +45,14 @@ def _populateNamespace(d):
d[local_name] = getattr(client._client, method)
d[local_name].__doc__ = client._client.system.methodHelp(method)
-def imagecapture(winName = None, outFile = None, resolution1 = None,
- resolution2 = None, x = 0, y = 0):
+def imagecapture(winName = None, outFile = None, width = None,
+ height = None, x = 0, y = 0):
if not outFile:
outFile = tempfile.mktemp('.png', 'ldtp_')
+ else:
+ outFile = os.path.expanduser(outFile)
- data = _remote_imagecapture(winName, resolution1, resolution2, x, y)
+ data = _remote_imagecapture(winName, width, height, x, y)
f = open(outFile, 'w')
f.write(b64decode(data))
f.close()
diff --git a/ldtpd/Makefile.am b/ldtpd/Makefile.am
new file mode 100644
index 0000000..7032350
--- /dev/null
+++ b/ldtpd/Makefile.am
@@ -0,0 +1,34 @@
+ldtpd_DATA = \
+ server_exception.py \
+ keypress_actions.py \
+ generic.py \
+ xmlrpc_daemon.py \
+ waiters.py \
+ mouse.py \
+ value.py \
+ text.py \
+ constants.py \
+ log.py \
+ core.py \
+ menu.py \
+ sequence_step.py \
+ utils.py \
+ page_tab_list.py \
+ table.py \
+ combo_box.py \
+ __init__.py
+
+pyc_DATA = $(ldtpd_DATA:.py=.pyc)
+pycdir = $(ldtpddir)
+
+%.pyc: %.py
+ $(PYTHON_CMD) -c "import py_compile; py_compile.compile ('$<', '$@')"
+
+EXTRA_DIST = \
+ $(ldtpd_DATA)
+
+CLEANFILES = \
+ $(pyc_DATA)
+
+MAINTAINERCLEANFILES = \
+ Makefile.in
diff --git a/ldtpd/combo_box.py b/ldtpd/combo_box.py
index 4596fcb..3de1313 100644
--- a/ldtpd/combo_box.py
+++ b/ldtpd/combo_box.py
@@ -234,20 +234,23 @@ class ComboBox(Utils):
@return: 1 on success.
@rtype: integer
'''
- obj = self._get_object(window_name, object_name)
- self._grab_focus(obj)
+ try:
+ obj = self._get_object(window_name, object_name)
+ self._grab_focus(obj)
- child_obj = self._get_combo_child_object_type(obj)
- if not child_obj:
- raise LdtpServerException('Unable to get combo box children')
+ child_obj = self._get_combo_child_object_type(obj)
+ if not child_obj:
+ return 0
- if child_obj == pyatspi.ROLE_LIST and \
- self._check_state(obj, pyatspi.STATE_FOCUSABLE):
- return 1
- elif child_obj == pyatspi.ROLE_MENU:
- if self._check_state(obj, pyatspi.STATE_VISIBLE) and \
- self._check_state(obj, pyatspi.STATE_SHOWING):
+ if child_obj == pyatspi.ROLE_LIST and \
+ self._check_state(obj, pyatspi.STATE_FOCUSABLE):
return 1
+ elif child_obj == pyatspi.ROLE_MENU:
+ if self._check_state(obj, pyatspi.STATE_VISIBLE) and \
+ self._check_state(obj, pyatspi.STATE_SHOWING):
+ return 1
+ except:
+ pass
return 0
def verifyshowlist(self, window_name, object_name):
@@ -280,20 +283,23 @@ class ComboBox(Utils):
@return: 1 on success.
@rtype: integer
'''
- obj = self._get_object(window_name, object_name)
- self._grab_focus(obj)
+ try:
+ obj = self._get_object(window_name, object_name)
+ self._grab_focus(obj)
- child_obj = self._get_combo_child_object_type(obj)
- if not child_obj:
- raise LdtpServerException('Unable to get combo box children')
+ child_obj = self._get_combo_child_object_type(obj)
+ if not child_obj:
+ return 0
- if child_obj == pyatspi.ROLE_LIST and \
- not self._check_state(obj, pyatspi.STATE_FOCUSABLE):
- return 1
- elif child_obj == pyatspi.ROLE_MENU:
- if not self._check_state(obj, pyatspi.STATE_VISIBLE) and \
- not self._check_state(obj, pyatspi.STATE_SHOWING):
+ if child_obj == pyatspi.ROLE_LIST and \
+ not self._check_state(obj, pyatspi.STATE_FOCUSABLE):
return 1
+ elif child_obj == pyatspi.ROLE_MENU:
+ if not self._check_state(obj, pyatspi.STATE_VISIBLE) and \
+ not self._check_state(obj, pyatspi.STATE_SHOWING):
+ return 1
+ except:
+ pass
return 0
def verifyselect(self, window_name, object_name, item_name):
@@ -312,32 +318,35 @@ class ComboBox(Utils):
@return: 1 on success.
@rtype: integer
'''
- obj = self._get_object(window_name, object_name)
- self._grab_focus(obj)
-
- child_obj = self._get_combo_child_object_type(obj)
- if not child_obj:
- raise LdtpServerException('Unable to get combo box children')
- if child_obj.getRole() == pyatspi.ROLE_LIST:
- for child in self._list_objects (child_obj):
- if child == child_obj:
- # As the _list_objects gives the current object as well
- # ignore it
- continue
- try:
- texti = child.queryText()
- text = texti.getText(0, texti.characterCount)
- except NotImplementedError:
- text = child.name
+ try:
+ obj = self._get_object(window_name, object_name)
+ self._grab_focus(obj)
+
+ child_obj = self._get_combo_child_object_type(obj)
+ if not child_obj:
+ return 0
+ if child_obj.getRole() == pyatspi.ROLE_LIST:
+ for child in self._list_objects (child_obj):
+ if child == child_obj:
+ # As the _list_objects gives the current object as well
+ # ignore it
+ continue
+ try:
+ texti = child.queryText()
+ text = texti.getText(0, texti.characterCount)
+ except NotImplementedError:
+ text = child.name
- if self._glob_match(item_name, text):
- return 1
- elif child_obj.getRole() == pyatspi.ROLE_MENU:
- for child in self._list_objects (child_obj):
- if child == child_obj:
- # As the _list_objects gives the current object as well
- # ignore it
- continue
- if self._glob_match(item_name, child.name):
- return 1
+ if self._glob_match(item_name, text):
+ return 1
+ elif child_obj.getRole() == pyatspi.ROLE_MENU:
+ for child in self._list_objects (child_obj):
+ if child == child_obj:
+ # As the _list_objects gives the current object as well
+ # ignore it
+ continue
+ if self._glob_match(item_name, child.name):
+ return 1
+ except:
+ pass
return 0
diff --git a/ldtpd/core.py b/ldtpd/core.py
index 10a1bf5..0b4b357 100644
--- a/ldtpd/core.py
+++ b/ldtpd/core.py
@@ -30,6 +30,7 @@ from keypress_actions import TypeAction
from server_exception import LdtpServerException
import os
import re
+import time
import pyatspi
import traceback
@@ -70,12 +71,18 @@ class Ldtpd(Utils, ComboBox, Table, Menu, PageTabList,
self._states[state.__repr__()] = state
return self._states
- def launchapp(self, cmd, args=[]):
+ def launchapp(self, cmd, args=[], delay = 5, env = 1):
'''
Launch application.
@param cmdline: Command line string to execute.
@type cmdline: string
+ @param args: Arguments to the application
+ @type args: list
+ @param delay: Delay after the application is launched
+ @type delay: int
+ @param env: GNOME accessibility environment to be set or not
+ @type env: int
@return: PID of new process
@rtype: integer
@@ -84,8 +91,16 @@ class Ldtpd(Utils, ComboBox, Table, Menu, PageTabList,
'''
os.environ['NO_GAIL'] = '0'
os.environ['NO_AT_BRIDGE'] = '0'
+ if env:
+ os.environ['GTK_MODULES'] = 'gail:atk-bridge'
+ os.environ['GNOME_ACCESSIBILITY'] = '1'
try:
process = subprocess.Popen([cmd]+args)
+ # Let us wait so that the application launches
+ try:
+ time.sleep(int(delay))
+ except ValueError:
+ time.sleep(5)
except Exception, e:
raise LdtpServerException(str(e))
os.environ['NO_GAIL'] = '1'
@@ -234,14 +249,17 @@ class Ldtpd(Utils, ComboBox, Table, Menu, PageTabList,
@return: 1 on success.
@rtype: integer
'''
- obj = self._get_object(window_name, object_name)
+ try:
+ obj = self._get_object(window_name, object_name)
- _state = obj.getState()
- _obj_state = _state.getStates()
- state = 'STATE_%s' % state.upper()
- if state in self._states and \
- self._states[state] in _obj_state:
- return 1
+ _state = obj.getState()
+ _obj_state = _state.getStates()
+ state = 'STATE_%s' % state.upper()
+ if state in self._states and \
+ self._states[state] in _obj_state:
+ return 1
+ except:
+ pass
return 0
def click(self, window_name, object_name):
@@ -360,9 +378,12 @@ class Ldtpd(Utils, ComboBox, Table, Menu, PageTabList,
@return: 1 on success 0 on failure.
@rtype: integer
'''
- obj = self._get_object(window_name, object_name)
+ try:
+ obj = self._get_object(window_name, object_name)
- return int(self._check_state(obj, pyatspi.STATE_CHECKED))
+ return int(self._check_state(obj, pyatspi.STATE_CHECKED))
+ except:
+ return 0
def verifyuncheck(self, window_name, object_name):
'''
@@ -378,9 +399,12 @@ class Ldtpd(Utils, ComboBox, Table, Menu, PageTabList,
@return: 1 on success 0 on failure.
@rtype: integer
'''
- obj = self._get_object(window_name, object_name)
+ try:
+ obj = self._get_object(window_name, object_name)
- return int(not self._check_state(obj, pyatspi.STATE_CHECKED))
+ return int(not self._check_state(obj, pyatspi.STATE_CHECKED))
+ except:
+ return 0
def stateenabled(self, window_name, object_name):
'''
@@ -396,9 +420,12 @@ class Ldtpd(Utils, ComboBox, Table, Menu, PageTabList,
@return: 1 on success 0 on failure.
@rtype: integer
'''
- obj = self._get_object(window_name, object_name)
+ try:
+ obj = self._get_object(window_name, object_name)
- return int(self._check_state(obj, pyatspi.STATE_ENABLED))
+ return int(self._check_state(obj, pyatspi.STATE_ENABLED))
+ except:
+ return 0
def getobjectlist(self, window_name):
'''
@@ -437,9 +464,9 @@ class Ldtpd(Utils, ComboBox, Table, Menu, PageTabList,
obj = self._get_object(window_name, object_name)
props = \
- ['child_index', 'key', 'obj_index', 'parent', 'class', 'children']
+ ['child_index', 'key', 'obj_index', 'parent', 'class', \
+ 'children', 'label', 'label_by']
- # TODO: label and label_by, what else am I missing?
return props
def getobjectproperty(self, window_name, object_name, prop):
@@ -464,6 +491,9 @@ class Ldtpd(Utils, ComboBox, Table, Menu, PageTabList,
elif prop == 'key':
obj = self._get_object(window_name, object_name) # A sanity check.
return object_name # For now, we only match exact names anyway.
+ elif prop == 'label':
+ obj = self._get_object(window_name, object_name) # A sanity check.
+ return obj.name
elif prop == 'obj_index':
role_count = {}
for gui in self._list_guis():
diff --git a/ldtpd/generic.py b/ldtpd/generic.py
index 4af75b3..55df4a4 100644
--- a/ldtpd/generic.py
+++ b/ldtpd/generic.py
@@ -29,8 +29,8 @@ from utils import Utils
from server_exception import LdtpServerException
class Generic(Utils):
- def imagecapture(self, winName = None, resolution1 = None,
- resolution2 = None, x = 0, y = 0):
+ def imagecapture(self, winName = None, width = None,
+ height = None, x = 0, y = 0):
if winName:
acc = None
for gui in self._list_guis():
@@ -47,12 +47,12 @@ class Generic(Utils):
window = gtk.gdk.get_default_root_window ()
size = window.get_size ()
pb = gtk.gdk.Pixbuf (gtk.gdk.COLORSPACE_RGB, False, 8,
- resolution1 or size [0],
- resolution2 or size [1])
+ width or size [0],
+ height or size [1])
pb = pb.get_from_drawable (window, window.get_colormap (),
x, y, 0, 0,
- resolution1 or size [0],
- resolution2 or size [1])
+ width or size [0],
+ height or size [1])
if pb:
tmpFile = tempfile.mktemp('.png', 'ldtpd_')
diff --git a/ldtpd/menu.py b/ldtpd/menu.py
index 28e5a5c..6911e9d 100644
--- a/ldtpd/menu.py
+++ b/ldtpd/menu.py
@@ -149,6 +149,84 @@ class Menu(Utils):
return 1
+ def menuitemenabled(self, window_name, object_name):
+ '''
+ Verify a menu item is enabled
+
+ @param window_name: Window name to look for, either full name,
+ LDTP's name convention, or a Unix glob.
+ @type window_name: string
+ @param object_name: Object name to look for, either full name,
+ LDTP's name convention, or a Unix glob. Or menu heirarchy
+ @type object_name: string
+
+ @return: 1 on success.
+ @rtype: integer
+ '''
+ try:
+ if re.search(';', object_name):
+ obj = self._get_menu_hierarchy(window_name, object_name)
+ else:
+ obj = self._get_object(window_name, object_name)
+
+ if self._check_state(obj, pyatspi.STATE_ENABLED):
+ return 1
+ except:
+ pass
+ return 0
+
+ def verifymenucheck(self, window_name, object_name):
+ '''
+ Verify a menu item is checked
+
+ @param window_name: Window name to look for, either full name,
+ LDTP's name convention, or a Unix glob.
+ @type window_name: string
+ @param object_name: Object name to look for, either full name,
+ LDTP's name convention, or a Unix glob. Or menu heirarchy
+ @type object_name: string
+
+ @return: 1 on success.
+ @rtype: integer
+ '''
+ try:
+ if re.search(';', object_name):
+ obj = self._get_menu_hierarchy(window_name, object_name)
+ else:
+ obj = self._get_object(window_name, object_name)
+
+ if self._check_state(obj, pyatspi.STATE_CHECKED):
+ return 1
+ except:
+ pass
+ return 0
+
+ def verifymenuuncheck(self, window_name, object_name):
+ '''
+ Verify a menu item is un-checked
+
+ @param window_name: Window name to look for, either full name,
+ LDTP's name convention, or a Unix glob.
+ @type window_name: string
+ @param object_name: Object name to look for, either full name,
+ LDTP's name convention, or a Unix glob. Or menu heirarchy
+ @type object_name: string
+
+ @return: 1 on success.
+ @rtype: integer
+ '''
+ try:
+ if re.search(';', object_name):
+ obj = self._get_menu_hierarchy(window_name, object_name)
+ else:
+ obj = self._get_object(window_name, object_name)
+
+ if not self._check_state(obj, pyatspi.STATE_CHECKED):
+ return 1
+ except:
+ pass
+ return 0
+
def invokemenu(self, window_name, object_name):
'''
Invoke menu item.
@@ -163,5 +241,5 @@ class Menu(Utils):
@return: 1 on success.
@rtype: integer
'''
- return self.press (window_name, object_name)
+ return self.press(window_name, object_name)
diff --git a/ldtpd/page_tab_list.py b/ldtpd/page_tab_list.py
index 602464c..000a685 100644
--- a/ldtpd/page_tab_list.py
+++ b/ldtpd/page_tab_list.py
@@ -108,18 +108,21 @@ class PageTabList(Utils):
@return: 1 on success 0 on failure
@rtype: integer
'''
- obj = self._get_object(window_name, object_name)
- self._grab_focus(obj)
-
try:
- for child in obj:
- if not child:
- continue
- if self._match_name_to_acc(tab_name, child) and \
- self._check_state(child, pyatspi.STATE_SELECTED):
- return 1
- except NotImplementedError:
- raise LdtpServerException('Unable to select page tab object.')
+ obj = self._get_object(window_name, object_name)
+ self._grab_focus(obj)
+
+ try:
+ for child in obj:
+ if not child:
+ continue
+ if self._match_name_to_acc(tab_name, child) and \
+ self._check_state(child, pyatspi.STATE_SELECTED):
+ return 1
+ except NotImplementedError:
+ pass
+ except:
+ pass
return 0
diff --git a/ldtpd/table.py b/ldtpd/table.py
index c3b8a14..369bd17 100644
--- a/ldtpd/table.py
+++ b/ldtpd/table.py
@@ -555,8 +555,11 @@ class Table(Utils):
@return: 1 on success 0 on failure.
@rtype: integer
'''
- text = self.getcellvalue(window_name, object_name, row_index, column)
- return int(self._glob_match(row_text, text))
+ try:
+ text = self.getcellvalue(window_name, object_name, row_index, column)
+ return int(self._glob_match(row_text, text))
+ except:
+ return 0
def doesrowexist(self, window_name, object_name, row_text):
'''
@@ -573,20 +576,23 @@ class Table(Utils):
@return: 1 on success 0 on failure.
@rtype: integer
- '''
- obj = self._get_object(window_name, object_name)
+ '''
+ try:
+ obj = self._get_object(window_name, object_name)
- def _searchString(acc):
- try:
- itext = acc.queryText()
- except NotImplementedError:
- return False
- return row_text == itext.getText(0,-1)
+ def _searchString(acc):
+ try:
+ itext = acc.queryText()
+ except NotImplementedError:
+ return False
+ return row_text == itext.getText(0,-1)
- results = pyatspi.findDescendant(obj, _searchString)
-
- return int(bool(results))
+ results = pyatspi.findDescendant(obj, _searchString)
+ return int(bool(results))
+ except:
+ return 0
+
def verifypartialtablecell(self, window_name, object_name, row_index,
column_index, row_text):
'''
@@ -608,8 +614,10 @@ class Table(Utils):
@return: 1 on success 0 on failure.
@rtype: integer
'''
- text = self.getcellvalue(window_name, object_name, row_index, column)
- if re.search(row_text, text):
- return 1
- else:
- return 0
+ try:
+ text = self.getcellvalue(window_name, object_name, row_index, column)
+ if re.search(row_text, text):
+ return 1
+ except:
+ pass
+ return 0
diff --git a/ldtpd/text.py b/ldtpd/text.py
index 533b2bb..57ca742 100644
--- a/ldtpd/text.py
+++ b/ldtpd/text.py
@@ -103,7 +103,8 @@ class Text(Utils):
return int(texti.setTextContents(data.encode('utf-8')))
- def gettextvalue(self, window_name, object_name):
+ def gettextvalue(self, window_name, object_name, startPosition = None,
+ endPosition = None):
'''
Get text value
@@ -113,6 +114,10 @@ class Text(Utils):
@param object_name: Object name to type in, either full name,
LDTP's name convention, or a Unix glob.
@type object_name: string
+ @param startPosition: Starting position of text to fetch
+ @type: startPosition: int
+ @param endPosition: Ending position of text to fetch
+ @type: endPosition: int
@return: text on success.
@rtype: string
@@ -134,7 +139,16 @@ class Text(Utils):
except NotImplementedError:
raise LdtpServerException('Text cannot be entered into object.')
- return texti.getText(0, texti.characterCount)
+ if startPosition and startPosition > 0:
+ start = startPosition
+ else:
+ start = 0
+ if endPosition and endPosition > start:
+ end = endPosition
+ else:
+ end = texti.characterCount
+
+ return texti.getText(start, end)
def verifypartialmatch(self, window_name, object_name, partial_text):
'''
@@ -152,9 +166,12 @@ class Text(Utils):
@return: 1 on success.
@rtype: integer
'''
- return int(self._glob_match(partial_text,
- self.gettextvalue(window_name,
- object_name)))
+ try:
+ return int(self._glob_match(partial_text,
+ self.gettextvalue(window_name,
+ object_name)))
+ except:
+ return 0
def verifysettext(self, window_name, object_name, text):
'''
@@ -242,9 +259,12 @@ class Text(Utils):
@return: 1 on success 0 on failure.
@rtype: integer
'''
- obj = self._get_object(window_name, object_name)
- self._grab_focus(obj)
- return int(self._check_state(obj, pyatspi.STATE_EDITABLE))
+ try:
+ obj = self._get_object(window_name, object_name)
+ self._grab_focus(obj)
+ return int(self._check_state(obj, pyatspi.STATE_EDITABLE))
+ except:
+ return 0
def getcharcount(self, window_name, object_name):
'''
diff --git a/ldtpd/utils.py b/ldtpd/utils.py
index dca0438..ad15b5d 100644
--- a/ldtpd/utils.py
+++ b/ldtpd/utils.py
@@ -72,13 +72,15 @@ class Utils:
if acc.name == name:
return 1
_object_name = self._ldtpize_accessible(acc)
- _object_name = '%s%s' % (_object_name[0],_object_name[1])
+ _object_name = '%s%s' % (_object_name[0], _object_name[1])
if _object_name == name:
return 1
if self._glob_match(name, acc.name):
return 1
if self._glob_match(name, _object_name):
return 1
+ if self._glob_match(re.sub(' ', '', name), _object_name):
+ return 1
return 0
def _match_name_to_appmap(self, name, appmap_name):
@@ -134,24 +136,33 @@ class Utils:
def _appmap_pairs(self, gui):
ldtpized_list = []
+ ldtpized_obj_index = {}
for obj in self._list_objects(gui):
abbrev_role, abbrev_name = self._ldtpize_accessible(obj)
+ if abbrev_role in ldtpized_obj_index:
+ ldtpized_obj_index[abbrev_role] += 1
+ else:
+ ldtpized_obj_index[abbrev_role] = 0
if abbrev_name == '':
ldtpized_name_base = abbrev_role
- ldtpized_name = '%s0' % ldtpized_name_base
+ ldtpized_name = '%s%d' % (ldtpized_name_base,
+ ldtpized_obj_index[abbrev_role])
else:
- ldtpized_name_base = '%s%s' % (abbrev_role,abbrev_name)
+ ldtpized_name_base = '%s%s' % (abbrev_role, abbrev_name)
ldtpized_name = ldtpized_name_base
i = 1
while ldtpized_name in ldtpized_list:
- ldtpized_name = '%s%d' % (ldtpized_name_base, i)
+ ldtpized_name = '%s%d' % (ldtpized_name_base,
+ i)
i += 1
ldtpized_list.append(ldtpized_name)
yield ldtpized_name, obj
def _get_menu_hierarchy(self, window_name, object_name):
_menu_hierarchy = re.split(';', object_name)
- obj = self._get_object(window_name, _menu_hierarchy [0])
+ # Get handle of menu
+ obj = self._get_object(window_name, _menu_hierarchy[0])
+ # Navigate all sub-menu under a menu
for _menu in _menu_hierarchy[1:]:
_flag = False
for _child in self._list_objects(obj):
@@ -159,12 +170,12 @@ class Utils:
# if the given object and child object matches
continue
if self._match_name_to_acc(_menu, _child):
+ obj = _child
_flag = True
break
if not _flag:
raise LdtpServerException (
"Menu item %s doesn't exist in hierarchy" % _menu)
- obj = self._get_object(window_name, _menu)
return obj
def _click_object(self, obj, action = 'click'):
diff --git a/ldtpd/value.py b/ldtpd/value.py
index f3cdf27..46c9684 100644
--- a/ldtpd/value.py
+++ b/ldtpd/value.py
@@ -47,7 +47,7 @@ class Value(Utils):
except NotImplementedError:
raise LdtpServerException('Value cannot be entered into object.')
- valuei.currentValue = float (data)
+ valuei.currentValue = float(data)
return 1
def getvalue(self, window_name, object_name):
@@ -105,17 +105,15 @@ class Value(Utils):
@return: 1 on success 0 on failure.
@rtype: 1
'''
- obj = self._get_object(window_name, object_name)
-
try:
+ obj = self._get_object(window_name, object_name)
valuei = obj.queryValue()
- except NotImplementedError:
- raise LdtpServerException('Value cannot be entered into object.')
- if valuei.currentValue == data:
- return 1
- else:
- return 0
+ if valuei.currentValue == data:
+ return 1
+ except:
+ pass
+ return 0
def getminvalue(self, window_name, object_name):
'''
@@ -200,12 +198,14 @@ class Value(Utils):
@return: 1 on success.
@rtype: integer
'''
- obj = self._get_object(window_name, object_name)
+ try:
+ obj = self._get_object(window_name, object_name)
- if self._check_state(obj, pyatspi.STATE_VERTICAL):
- return 1
- else:
- return 0
+ if self._check_state(obj, pyatspi.STATE_VERTICAL):
+ return 1
+ except:
+ pass
+ return 0
def verifysliderhorizontal(self, window_name, object_name):
'''
@@ -221,12 +221,14 @@ class Value(Utils):
@return: 1 on success.
@rtype: integer
'''
- obj = self._get_object(window_name, object_name)
+ try:
+ obj = self._get_object(window_name, object_name)
- if self._check_state(obj, pyatspi.STATE_HORIZONTAL):
- return 1
- else:
- return 0
+ if self._check_state(obj, pyatspi.STATE_HORIZONTAL):
+ return 1
+ except:
+ pass
+ return 0
def verifyscrollbarvertical(self, window_name, object_name):
'''
@@ -242,12 +244,14 @@ class Value(Utils):
@return: 1 on success.
@rtype: integer
'''
- obj = self._get_object(window_name, object_name)
+ try:
+ obj = self._get_object(window_name, object_name)
- if self._check_state(obj, pyatspi.STATE_VERTICAL):
- return 1
- else:
- return 0
+ if self._check_state(obj, pyatspi.STATE_VERTICAL):
+ return 1
+ except:
+ pass
+ return 0
def verifyscrollbarhorizontal(self, window_name, object_name):
'''
@@ -263,12 +267,14 @@ class Value(Utils):
@return: 1 on success.
@rtype: integer
'''
- obj = self._get_object(window_name, object_name)
+ try:
+ obj = self._get_object(window_name, object_name)
- if self._check_state(obj, pyatspi.STATE_HORIZONTAL):
- return 1
- else:
- return 0
+ if self._check_state(obj, pyatspi.STATE_HORIZONTAL):
+ return 1
+ except:
+ pass
+ return 0
def scrollup(self, window_name, object_name):
'''
diff --git a/ldtputils/Makefile.am b/ldtputils/Makefile.am
new file mode 100644
index 0000000..170bba6
--- /dev/null
+++ b/ldtputils/Makefile.am
@@ -0,0 +1,17 @@
+ldtputils_DATA = \
+ __init__.py
+
+pyc_DATA = $(ldtputils_DATA:.py=.pyc)
+pycdir = $(ldtputilsdir)
+
+%.pyc: %.py
+ $(PYTHON_CMD) -c "import py_compile; py_compile.compile ('$<', '$@')"
+
+EXTRA_DIST = \
+ $(ldtputils_DATA)
+
+CLEANFILES = \
+ $(pyc_DATA)
+
+MAINTAINERCLEANFILES = \
+ Makefile.in
diff --git a/ooldtp/Makefile.am b/ooldtp/Makefile.am
new file mode 100644
index 0000000..f7ca285
--- /dev/null
+++ b/ooldtp/Makefile.am
@@ -0,0 +1,18 @@
+ooldtp_DATA = \
+ _context.py \
+ __init__.py
+
+pyc_DATA = $(ooldtp_DATA:.py=.pyc)
+pycdir = $(ooldtpdir)
+
+%.pyc: %.py
+ $(PYTHON_CMD) -c "import py_compile; py_compile.compile ('$<', '$@')"
+
+EXTRA_DIST = \
+ $(ooldtp_DATA)
+
+CLEANFILES = \
+ $(pyc_DATA)
+
+MAINTAINERCLEANFILES = \
+ Makefile.in