This tool is brilliant! It was precisely what I've been searching for, and I've taken several days to pore over the documentation and this thread, and to explore Test Controller's scripting capabilities. Having said that, I've run into some bugs (or maybe some quirks) and I have some questions I'd like to put to you.
First, a bug: The "Script List" popup fails to list any of the scripts I created (and, in fact, is completely blank except for when I sweep the mouse cursor over the dialog box buttons, which individually reappear when I do so). Here's what the dialog box looks like after I've painted the mouse cursor all over it:

Here's the debug output:
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 5, Size: 5
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at dk.hkj.devices.LoadDeviceConfig.getIndex(LoadDeviceConfig.java:122)
at dk.hkj.main.PopupScriptList$3.prepareRenderer(PopupScriptList.java:118)
at javax.swing.plaf.basic.BasicTableUI.paintCell(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI.paintCells(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
at javax.swing.plaf.ComponentUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JViewport.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JLayeredPane.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at java.awt.GraphicsCallback$PaintCallback.run(Unknown Source)
at sun.awt.SunGraphicsCallback.runOneComponent(Unknown Source)
at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
at java.awt.Container.paint(Unknown Source)
at java.awt.Window.paint(Unknown Source)
at javax.swing.RepaintManager$4.run(Unknown Source)
at javax.swing.RepaintManager$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$1200(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
For what it's worth, initially the dialog did work as expected. At some point while I created more scripts and files containing scripts, it stopped working.
Next, the documentation states:
To check the type of a variable use type(v), the normal types will be long/double/string, but there are also complex/dateTime/array/struct/...
This seems to suggest that it's possible to declare a variable as a struct; how do we go about doing so? Is such a thing possible right now? (Being able to do so would be amazing...and being able to declare arrays of structs would be even more so!)
Finally, I'm not clear on how the iterator variable works in the #FOREACH command. I tried doing something like this, using #FOREACH to iterate through an array of arbitrary size:
=var my_array = array("some value", "another value", "and so on")
#foreach item my_array
#echo (item)
#endforeach
This code results in this output:
;; my_array
...but I was hoping for something like this output:
;; some value
;; another value
;; and so on
Clearly I am misunderstanding the command's usage. Could you clarify it?
Thanks again for your work on this really great tool!