Version 8.0.1 |
The Graphical Editing Framework (GEF) is a set
of Eclipse plugins for creating editors that support visual editing of arbitrary models.
This framework is very popular and QF-Test has supported recording and playback of GEF
items for a long time (since about version 2.2). It is also a good example for the
power of the ItemResolver
concept (see section 53.4),
because the gef
Jython module contains an implementation of just that
interface.
The gef
module can deal with GEF editors at a generic level and even
support several editors at once. Though reasonable item names are provided out of the
box also for GMF applications, there are limits to what can be determined automatically.
Depending on the underlying model classes, there might still remain some work for you:
Implementing custom resolvers to provide useful names and values for your items.
The actual GEF component is the FigureCanvas
. This control displays
Figures
which represent EditParts
. When recording a mouse
click on such an element, QF-Test does not register a pure 'Mouse event' node for
the canvas component with the corresponding (x,y) position but tries to recognize
the object under the mouse cursor. For example, the recorded 'QF-Test component ID' may look
like
canvas@/Diagram/My ship/ShipLargeCargo (wine)
canvas@Connection-2
canvas@/Diagram/Rectangle 16329001
where "canvas" is the 'QF-Test ID' of the FigureCanvas
component, followed by
the item index of the recognized EditPart
(see section 5.9). EditParts
reside in a tree like hierarchy which
is reflected in the index by a path separator '/'. The names of the individual items
are generated as follows:
EditPart
always reads "Diagram".
As one can imagine, those generated item names may not always be useful. For example, items might be deleted so that the recorded index is not longer valid. Or the generated item name is unstable as "Rectangle 16329001" in the GEF Shapes example: The number is random and when restarting the application a different one will be created. Three options exist to overcome the problem:
/0/1
tells nothing about an item.
toString()
method of the item's model. It
would make live easy for you, but only if the developers are cooperative.
ItemNameResolver2
. This is the tough course but
unfortunately the most likely scenario. It is covered in the next section.
As stated in section 53.1, an ItemNameResolver2
is the hook to change or provide names for items. To get started, insert a new
Jython 'SUT script' in the 'Extras' node with the following
code:
| ||||
Example 53.35: Get started with a GEF ItemNameResolver2 |
To ease the installation of the resolver we use the resolvers
module
described in section 53.1. The resolver gets registered for the
FigureCanvas
class where the items reside. The default item name
provided by QF-Test is supplied as the last argument to our function
getItemName()
. Now run the script, press the record button and then simply
move the mouse over your figures on the canvas - supposing you have created some of
them previously. Note that this first resolver implementation does nothing but print
out out some information into the terminal, something like
name: Rectangle 16329001
item: org.eclipse.gef.examples.shapes.parts.ShapeEditPart
model: org.eclipse.gef.examples.shapes.model.RectangularShape
The question is now: Does the model of the GEF EditPart
provide any
property that might be used as name for the item? The answer in the case of the GEF
Shapes example is "No", and hopefully you are in a better situation with your
application. To find out insert a line
print dir(model)
in the getItemName()
function and run the script again. Now you will
also see the methods of the model when moving the mouse over the items in record
mode. With a bit of luck you will find methods like getId()
or
getLabel()
and can create a resolver like this:
| ||||
Example 53.36: A simple ItemNameResolver2 |
Let's go back to the GEF Shapes example where we don't have such useful methods. Only geometry information is available for the shapes and that is not really helpful. At least we can distinguish between rectangles and ellipses. To make the item names unique we simply add a child index as shown in the following resolver:
| ||||
Example 53.37: An ItemNameResolver2 for GEF Shapes |
With this resolver in place, the item index for a rectangle becomes
/Diagram/Rectangle 1
where the trailing number is the child index of the item. The above implementation
also provides names for the connections by calling getItemName()
recursively for the source and the target item of the connection. Checking the types
with qf.isInstance()
(see section 49.6) will save you the need to import the GEF classes,
something that is not trivial.
Once your resolver is working fine you should move the script into your 'Setup' sequence right behind the 'Wait for client to connect' node. This way the resolver will be registered automatically when the SUT starts.
Usually a GEF editor consists of two parts. Having focused so far on the canvas
where you draw the figures, we now take a look at the palette where you select the
kind of figure to draw (e.g. 'Rectangle', 'Ellipse' or 'Connection'). Its entries
look like tool buttons but actually the palette is a FigureCanvas
too.
You will be glad to know that this one works out of the box, that is without
implementing an ItemNameResolver2
. When you click for example on the
'Rectangle' button, QF-Test recognizes a
/Palette Root/Palette Container (Shapes)/Palette Entry (Rectangle)
item. What will happen when you record a check (cf. section 4.3) for the 'Object value' for this button? You may expect to get the button text 'Rectangle' but in fact the value of this item is
Palette Entry (Rectangle)
The reason is that by default name and value of an item are the same. To alter this
behavior and provide customized values you need to implement an
ItemValueResolver2
. This interface is very similar to the
ItemNameResolver2
above. For the palette we can code the
following one:
| ||||
Example 53.38: An ItemValueResolver2 for the GEF Shapes palette |
The method getLabel()
returns the text as displayed in the palette.
Last update: 9/10/2024 Copyright © 1999-2024 Quality First Software GmbH |