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 Emulators

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 Emulators

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 Emulators

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.

Note

The order in which objects are returned is not guaranteed.

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 Emulators

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.

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.

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.

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 Emulators 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