autopilot.introspection - Autopilot introspection internals

Package for introspection support.

This package contains the internal implementation of the autopilot introspection mechanism, and probably isn’t useful to most test authors.

autopilot.introspection.get_proxy_object_for_existing_process(pid=None, dbus_bus='session', connection_name=None, process=None, object_path='/com/canonical/Autopilot/Introspection', application_name=None, emulator_base=None)[source]

Return a single proxy object for an application that is already running (i.e. launched outside of Autopilot).

Searches on the given bus (supplied by dbus_bus) for an application matching the search criteria, creating the proxy object using the supplied custom emulator emulator_base (defaults to None).

For example for an application on the system bus where the applications PID is known:

app_proxy = get_proxy_object_for_existing_process(pid=app_pid)

Multiple criteria are allowed, for instance you could search on pid and connection_name:

app_proxy = get_proxy_object_for_existing_process(
    pid=app_pid, connection_name='org.gnome.gedit')

If the application from the previous example was on the system bus:

app_proxy = get_proxy_object_for_existing_process(
    dbus_bus='system', pid=app_pid, connection_name='org.gnome.gedit')

It is possible to search for the application given just the applications name. An example for an application running on a custom bus searching using the applications name:

app_proxy = get_proxy_object_for_existing_process(
    application_name='qmlscene',
    dbus_bus='unix:abstract=/tmp/dbus-IgothuMHNk')
Parameters:
  • pid – The PID of the application to search for.
  • dbus_bus – A string containing either ‘session’, ‘system’ or the custom buses name (i.e. ‘unix:abstract=/tmp/dbus-IgothuMHNk’).
  • connection_name – A string containing the DBus connection name to use with the search criteria.
  • object_path – A string containing the object path to use as the search criteria. Defaults to autopilot.introspection.constants.AUTOPILOT_PATH.
  • application_name – A string containing the applications name to search for.
  • emulator_base – The custom emulator to create the resulting proxy object with.
Raises:
  • ProcessSearchError – if no search criteria match.
  • RuntimeError – if the search criteria results in many matches.
  • RuntimeError – if both process and pid are supplied, but process.pid != pid.

This module contains the code to retrieve state via DBus calls.

Under normal circumstances, the only thing you should need to use from this module is the DBusIntrospectableObject class.

exception autopilot.introspection.dbus.StateNotFoundError(class_name=None, **filters)[source]

Raised when a piece of state information is not found.

This exception is commonly raised when the application has destroyed (or not yet created) the object you are trying to access in autopilot. This typically happens for a number of possible reasons:

class autopilot.introspection.dbus.DBusIntrospectionObject(state_dict, path, backend)[source]

A class that supports transparent data retrieval from the application under test.

This class is the base class for all objects retrieved from the application under test. It handles transparently refreshing attribute values when needed, and contains many methods to select child objects in the introspection tree.

get_children_by_type(desired_type, **kwargs)[source]

Get a list of children of the specified type.

Keyword arguments can be used to restrict returned instances. For example:

get_children_by_type('Launcher', monitor=1)

will return only Launcher instances that have an attribute ‘monitor’ that is equal to 1. The type can also be specified as a string, which is useful if there is no emulator class specified:

get_children_by_type('Launcher', monitor=1)

Note however that if you pass a string, and there is an emulator class defined, autopilot will not use it.

Parameters:desired_type – Either a string naming the type you want, or a class of the type you want (the latter is used when defining custom emulators)

See also

Tutorial Section Writing Custom Proxy Classes

get_properties()[source]

Returns a dictionary of all the properties on this class.

This can be useful when you want to log all the properties exported from your application for a particular object. Every property in the returned dictionary can be accessed as attributes of the object as well.

get_children()[source]

Returns a list of all child objects.

This returns a list of all children. To return only children of a specific type, use get_children_by_type. To get objects further down the introspection tree (i.e.- nodes that may not necessarily be immeadiate children), use select_single and select_many.

get_parent()[source]

Returns the parent of this object.

If this object has no parent (i.e.- it is the root of the introspection tree). Then it returns itself.

select_single(type_name='*', **kwargs)[source]

Get a single node from the introspection tree, with type equal to type_name and (optionally) matching the keyword filters present in kwargs.

You must specify either type_name, keyword filters or both.

This method searches recursively from the instance this method is called on. Calling select_single on the application (root) proxy object will search the entire tree. Calling select_single on an object in the tree will only search it’s descendants.

Example usage:

app.select_single('QPushButton', objectName='clickme')
# returns a QPushButton whose 'objectName' property is 'clickme'.

If nothing is returned from the query, this method raises StateNotFoundError.

Parameters:

type_name – Either a string naming the type you want, or a class of the appropriate type (the latter case is for overridden emulator classes).

Raises:
  • ValueError – if the query returns more than one item. If you want more than one item, use select_many instead.
  • TypeError – if neither type_name or keyword filters are provided.
  • StateNotFoundError – if the requested object was not found.

See also

Tutorial Section Writing Custom Proxy Classes

wait_select_single(type_name='*', **kwargs)[source]

Get a proxy object matching some search criteria, retrying if no object is found until a timeout is reached.

This method is identical to the select_single method, except that this method will poll the application under test for 10 seconds in the event that the search criteria does not match anything.

This method will return single proxy object from the introspection tree, with type equal to type_name and (optionally) matching the keyword filters present in kwargs.

You must specify either type_name, keyword filters or both.

This method searches recursively from the proxy object this method is called on. Calling select_single on the application (root) proxy object will search the entire tree. Calling select_single on an object in the tree will only search it’s descendants.

Example usage:

app.wait_select_single('QPushButton', objectName='clickme')
# returns a QPushButton whose 'objectName' property is 'clickme'.
# will poll the application until such an object exists, or will
# raise StateNotFoundError after 10 seconds.

If nothing is returned from the query, this method raises StateNotFoundError after 10 seconds.

Parameters:

type_name – Either a string naming the type you want, or a class of the appropriate type (the latter case is for overridden emulator classes).

Raises:
  • ValueError – if the query returns more than one item. If you want more than one item, use select_many instead.
  • TypeError – if neither type_name or keyword filters are provided.
  • StateNotFoundError – if the requested object was not found.

See also

Tutorial Section Writing Custom Proxy Classes

select_many(type_name='*', **kwargs)[source]

Get a list of nodes from the introspection tree, with type equal to type_name and (optionally) matching the keyword filters present in kwargs.

You must specify either type_name, keyword filters or both.

This method searches recursively from the instance this method is called on. Calling select_many on the application (root) proxy object will search the entire tree. Calling select_many on an object in the tree will only search it’s descendants.

Example Usage:

app.select_many('QPushButton', enabled=True)
# returns a list of QPushButtons that are enabled.

As mentioned above, this method searches the object tree recursively:

file_menu = app.select_one('QMenu', title='File')
file_menu.select_many('QAction')
# returns a list of QAction objects who appear below file_menu in
# the object tree.

Warning

The order in which objects are returned is not guaranteed. It is bad practise to write tests that depend on the order in which this method returns objects. (see Do Not Depend on Object Ordering for more information).

If you only want to get one item, use select_single instead.

Parameters:type_name – Either a string naming the type you want, or a class of the appropriate type (the latter case is for overridden emulator classes).
Raises:TypeError – if neither type_name or keyword filters are provided.

See also

Tutorial Section Writing Custom Proxy Classes

refresh_state()[source]

Refreshes the object’s state.

You should probably never have to call this directly. Autopilot automatically retrieves new state every time this object’s attributes are read.

Raises:StateNotFound – if the object in the application under test has been destroyed.
get_all_instances()[source]

Get all instances of this class that exist within the Application state tree.

For example, to get all the LauncherIcon instances:

icons = LauncherIcon.get_all_instances()

Warning

Using this method is slow - it requires a complete scan of the introspection tree. You should only use this when you’re not sure where the objects you are looking for are located. Depending on the application you are testing, you may get duplicate results using this method.

Returns:List (possibly empty) of class instances.
get_root_instance()[source]

Get the object at the root of this tree.

This will return an object that represents the root of the introspection tree.

get_state_by_path(piece)[source]

Get state for a particular piece of the state tree.

You should probably never need to call this directly.

Parameters:piece – an XPath-like query that specifies which bit of the tree you want to look at.
Raises:TypeError – on invalid piece parameter.
get_new_state()[source]

Retrieve a new state dictionary for this class instance.

You should probably never need to call this directly.

Note

The state keys in the returned dictionary are not translated.

wait_until_destroyed(timeout=10)[source]

Block until this object is destroyed in the application.

Block until the object this instance is a proxy for has been destroyed in the applicaiton under test. This is commonly used to wait until a UI component has been destroyed.

Parameters:timeout – The number of seconds to wait for the object to be destroyed. If not specified, defaults to 10 seconds.
Raises:RuntimeError – if the method timed out.
get_class_query_string()[source]

Get the XPath query string required to refresh this class’s state.

make_introspection_object(dbus_tuple)[source]

Make an introspection object given a DBus tuple of (path, state_dict).

This only works for classes that derive from DBusIntrospectionObject.

Returns:A proxy object that derives from DBusIntrospectionObject
Raises:ValueError – if more than one class is appropriate for this dbus_tuple
print_tree(output=None, maxdepth=None, _curdepth=0)[source]

Print properties of the object and its children to a stream.

When writing new tests, this can be called when it is too difficult to find the widget or property that you are interested in in “vis”.

Warning

Do not use this in production tests, this is expensive and not at all appropriate for actual testing. Only call this temporarily and replace with proper select_single/select_many calls.

Parameters:
  • output – A file object or path name where the output will be written to. If not given, write to stdout.
  • maxdepth – If given, limit the maximum recursion level to that number, i. e. only print children which have at most maxdepth-1 intermediate parents.
no_automatic_refreshing(*args, **kwds)[source]

Context manager function to disable automatic DBus refreshing when retrieving attributes.

Example usage:

with instance.no_automatic_refreshing():
# access lots of attributes.

This can be useful if you need to check lots of attributes in a tight loop, or if you want to atomicaly check several attributes at once.

classmethod validate_dbus_object(path, _state)[source]

Return whether this class is the appropriate proxy object class for a given dbus path and state.

The default version matches the name of the dbus object and the class. Subclasses of CustomProxyObject can override it to define a different validation method.

Parameters:
  • path – The dbus path of the object to check
  • state – The dbus state dict of the object to check (ignored in default implementation)
Returns:

Whether this class is appropriate for the dbus object

class autopilot.introspection.dbus.CustomEmulatorBase(state_dict, path, backend)

This class must be used as a base class for any custom emulators defined within a test case.

See also

Tutorial Section Writing Custom Proxy Classes
Information on how to write custom emulators.

Autopilot proxy type support.

This module defines the classes that are used for all attributes on proxy objects. All proxy objects contain attributes that transparently mirror the values present in the application under test. Autopilot takes care of keeping these values up to date.

Object attributes fall into two categories. Attributes that are a single string, boolean, or integer property are sent directly across DBus. These are called “plain” types, and are stored in autopilot as instnaces of the PlainType class. Attributes that are more complex (a rectangle, for example) are called “complex” types, and are split into several component values, sent across dbus, and are then reconstituted in autopilot into useful objects.

class autopilot.introspection.types.PlainType[source]

Plain type support in autopilot proxy objects.

Instances of this class will be used for all plain attrubites. The word “plain” in this context means anything that’s marshalled as a string, boolean or integer type across dbus.

Instances of these classes can be used just like the underlying type. For example, given an object property called ‘length’ that is marshalled over dbus as an integer value, the following will be true:

>>> isinstance(object.length, PlainType)
True
>>> isinstance(object.length, int)
True
>>> print(object.length)
123
>>> print(object.length + 32)
155

However, a special case exists for boolean values: because you cannot subclass from the ‘bool’ type, the following check will fail ( object.visible is a boolean property):

>>> isinstance(object.visible, bool)
False

However boolean values will behave exactly as you expect them to.

class autopilot.introspection.types.Rectangle(*args, **kwargs)[source]

The RectangleType class represents a rectangle in cartesian space.

To construct a rectangle, pass the x, y, width and height parameters in to the class constructor:

my_rect = Rectangle(12,13,100,150)

These attributes can be accessed either using named attributes, or via sequence indexes:

>>>my_rect = Rectangle(12,13,100,150)
>>> my_rect.x == my_rect[0] == 12
True
>>> my_rect.y == my_rect[1] == 13
True
>>> my_rect.w == my_rect[2] == 100
True
>>> my_rect.h == my_rect[3] == 150
True

You may also access the width and height values using the width and height properties:

>>> my_rect.width == my_rect.w
True
>>> my_rect.height == my_rect.h
True

Rectangles can be compared using == and !=, either to another Rectangle instance, or to any mutable sequence type:

>>> my_rect == [12, 13, 100, 150]
True
>>> my_rect != Rectangle(1,2,3,4)
True
class autopilot.introspection.types.Point(*args, **kwargs)[source]

The Point class represents a 2D point in cartesian space.

To construct a Point, pass in the x, y parameters to the class constructor:

>>> my_point = Point(50,100)

These attributes can be accessed either using named attributes, or via sequence indexes:

>>> my_point.x == my_point[0] == 50
True
>>> my_point.y == my_point[1] == 100
True

Point instances can be compared using == and !=, either to another Point instance, or to any mutable sequence type with the correct number of items:

>>> my_point == [50, 100]
True
>>> my_point != Point(5, 10)
True
class autopilot.introspection.types.Size(*args, **kwargs)[source]

The Size class represents a 2D size in cartesian space.

To construct a Size, pass in the width, height parameters to the class constructor:

>>> my_size = Size(50,100)

These attributes can be accessed either using named attributes, or via sequence indexes:

>>> my_size.width == my_size.w == my_size[0] == 50
True
>>> my_size.height == my_size.h == my_size[1] == 100
True

Size instances can be compared using == and !=, either to another Size instance, or to any mutable sequence type with the correct number of items:

>>> my_size == [50, 100]
True
>>> my_size != Size(5, 10)
True
class autopilot.introspection.types.DateTime(*args, **kwargs)[source]

The DateTime class represents a date and time in the UTC timezone.

DateTime is constructed by passing a unix timestamp in to the constructor. Timestamps are expressed as the number of seconds since 1970-01-01T00:00:00 in the UTC timezone:

>>> my_dt = DateTime(1377209927)

This timestamp can always be accessed either using index access or via a named property:

>>> my_dt[0] == my_dt.timestamp == 1377209927
True

DateTime objects also expose the usual named properties you would expect on a date/time object:

>>> my_dt.year
2013
>>> my_dt.month
8
>>> my_dt.day
22
>>> my_dt.hour
22
>>> my_dt.minute
18
>>> my_dt.second
47

Two DateTime objects can be compared for equality:

>>> my_dt == DateTime(1377209927)
True

You can also compare a DateTime with any mutable sequence type containing the timestamp (although this probably isn’t very useful for test authors):

>>> my_dt == [1377209927]
True

Finally, you can also compare a DateTime instance with a python datetime instance:

>>> my_datetime = datetime.datetime.fromutctimestamp(1377209927)
True

DateTime instances can be converted to datetime instances:

>>> isinstance(my_dt.datetime, datetime.datetime)
True
class autopilot.introspection.types.Time(*args, **kwargs)[source]

The Time class represents a time, without a date component.

You can construct a Time instnace by passing the hours, minutes, seconds, and milliseconds to the class constructor:

>>> my_time = Time(12, 34, 01, 23)

The values passed in must be valid for their positions (ie..- 0-23 for hours, 0-59 for minutes and seconds, and 0-999 for milliseconds). Passing invalid values will cause a ValueError to be raised.

The hours, minutes, seconds, and milliseconds can be accessed using either index access or named properties:

>>> my_time.hours == my_time[0] == 12
True
>>> my_time.minutes == my_time[1] == 34
True
>>> my_time.seconds == my_time[2] == 01
True
>>> my_time.milliseconds == my_time[3] == 23
True

Time instances can be compared to other time instances, any mutable sequence containing four integers, or datetime.time instances:

>>> my_time == Time(12, 34, 01, 23)
True
>>> my_time == Time(1,2,3,4)
False

>>> my_time == [12, 34, 01, 23]
True

>>> my_time == datetime.time(12, 34, 01, 23000)
True

Note that the Time class stores milliseconds, while the datettime.time class stores microseconds.

Finally, you can get a datetime.time instance from a Time instance:

>>> isinstance(my_time.time, datetime.time)
True