Re: Abbot
Timothy Wall <twall <at> users.sourceforge.net>
2006-06-09 02:53:20 GMT
On Jun 8, 2006, at 2:59 AM, Hendrik Faenger wrote:
> Dear Mr. Wall,
>
> we are using Abbot for GUI Testing.
> Thank you for this great pice of software. We are trying to get a
> lot of test on their way for
> our Software.
>
> Since our application has serveral custom GUI Elements, we need
> serveral custom tester's and recorders.
> Also we like to have similar functionalty like your Image Capture
> Function. (pressing a hotKey
> and performe some data capturing)
>
> The ScriptEditor class was modified to archive this.
> But to seperate our code from Abbot's one, some new functionality
> would be nice, which allows to add more "hot key" functions.
>
> Browsing the code in original ScriptEditor.java brings:
>
> if (!handleEditorTransient(event)
> && !handleRecordingControl(event)
> && !handleImageCaptureControl(event)
> && !handleComponentSelection(event)
> && recorder != null && recording && !isFiltered) {
> Log.debug("recorder process event");
> try {
> recorder.record(event);
> }
>
> To add new functions here we have to write and insert our new
> function here. This is a bad idea, because in the case of an update
> of the Abbott Framework all changes would be lost.
I never considered hot keys to be an area requiring extension, but
then who ever does?
>
> A better approch would be the use of an "PlugIn" System.
>
> I've tried to put up a solution:
>
> 1. Define an Interface
>
> package abbot.editor;
> import java.awt.AWTEvent;
>
> public interface AbbotPlugIn {
> public boolean handleEvent(AWTEvent e);
> }
>
>
> 2. Adding new functions to the ScriptEditor.java:
>
> private static Vector<AbbotPlugIn> plugInVector = new
> Vector<AbbotPlugIn>();
>
> public void addPlugin(AbbotPlugIn p) {
> if (!plugInVector.contains(p)) plugInVector.add(p);
> }
>
> public void removePlugin(AbbotPlugIn p) {
> if (plugInVector.contains(p)) plugInVector.remove(p);
> }
>
> private boolean handlePlugins(AWTEvent e) {
> boolean ret=false;
> for (int i=0;i<plugInVector.size();i++) {
> ret&=plugInVector.get(i).handleEvent(e);
> }
> return ret;
> }
>
> private void scanAddPlugIns() {
> String path=this.getClass().getResource
> ("ScriptEditor.java").getPath();
> path=path.substring(1,path.lastIndexOf("/"))+"/plugins/";
> String[] dir;
> File testd= new File(path);
> if (testd.isDirectory()) {
> dir = testd.list();
> for (int i=0;i<dir.length;i++) {
> if (dir[i].startsWith("PlugIn") && dir[i].endsWith
> (".class")) {
> dir[i] = dir[i].substring(0,dir[i].indexOf(".class"));
> System.out.println("Plugin found: "+dir[i]);
> try {
> Class aClass = ClassLoader.getSystemClassLoader().loadClass
> ("abbot.editor.plugins."+dir[i]);
> Object plugin = aClass.getConstructor(this.getClass
> ()).newInstance(this);
> if (plugin instanceof AbbotPlugIn) {
> this.addPlugin((AbbotPlugIn)plugin);
> }
> } catch (ClassNotFoundException e) {
> Log.debug("Plugin load failed.");
> } catch (SecurityException e) {
> Log.debug("Plugin load failed.");
> } catch (NoSuchMethodException e) {
> Log.debug("Plugin load failed.");
> } catch (IllegalArgumentException e) {
> Log.debug("Plugin load failed.");
> } catch (InstantiationException e) {
> Log.debug("Plugin load failed.");
> } catch (IllegalAccessException e) {
> Log.debug("Plugin load failed.");
> } catch (InvocationTargetException e) {
> Log.debug("Plugin load failed.");
> }
> }
> }
> }
> }
>
> 3. Modifiy the ScriptEditor.java:
>
> if (!handleEditorTransient(event)
> && !handleRecordingControl(event)
> && !handleImageCaptureControl(event)
> && !handlePlugins(event)
> && !handleComponentSelection(event)
> && recorder != null && recording && !isFiltered) {
> Log.debug("recorder process event");
> try {
> recorder.record(event);
> }
>
>
> Plugins must start with Plugin and must be in the pakage
> abbot.editor.plugins to be reconized.
> Also they had to implement the AbbotPlugIn Interface.
>
> This would make it possible to do a clear seperation between your's
> und our code.
>
> Since there is enough time during the record phase, time is not
> critical and therefore the introduction of
> the new PlugInHandler should't be a problem.
>
>
> It would be great if you could think about this suggestion and if
> you like it, integrate it into the Abbot's Testing Framework.
That looks like the start of a good idea. Let me contribute a bit.
If you're just thinking about handling "hotkeys", it might be better
to establish an InputMap and an ActionMap for actions to be invoked
during recording. The real issue is how to dynamically define and
load actions. Since these things don't need to be changed while the
editor is running (or do they?), a custom wrapper class could hotkey
mappings prior to launching the editor.
The scheme you suggest, however, could be applied such that some of
the existing "options" could be converted to plugins, which might
make that bit of code a little cleaner (assuming there are no issues
with order of checking).
It's far simpler to trigger from matching keystrokes than to parse
generic AWTEvents; the "plugins" should be able to simply specify
what event triggers them, then not have to worry about checking
whether it's an appropriate event.
Another alternative might be to simply refactor the event handling
such that there exists a method which can be overridden to add the
functionality you wish. This avoids the overhead and complexity of
making a generic plugin system.
Timothy Wall
http://abbot.sf.net