Testing keyboard input with java.awt.Robot - java

I have a test that exercises a custom Swing component using java.awt.Robot. I'd like to run the test in our build server, but the build servers run on locked windows machines, and Robot.keyPress(char) doesn't work with the screen locked. The keystrokes I'm sending are sometimes things like down arrow and backspace, so sending them directly to the document isn't helpful.
Currently I'm just using junit's Assume to skip the tests if keyboard entry doesn't work on the first try, but I'd like to leave these test enabled. I would assume someone out there is running these kinds of tests against a Swing gui. Any ideas?

A stab in the dark: perhaps a VM (like VirtualBox) could be running in the background, but would for all intents and purposes be "awake and unlocked" as far as the robot knows. The virtual box would run your unit tests.

have you tried using the headless mode of java ?
I guess java.awt.Robot won't work in this case, since it specifically depends upon awt being loaded. in such a case, one should better rely upon gui testing frameworks, like the cool (and running in headless mode) fest-swing.

Related

Get java.awt.Robot to interact only with the test app

I doubt whether there's a solution to this but thought I'd ask anyway.
java.awt.Robot is very useful for unit testing, to simulate user input/action. The trouble is you can't then do anything else on your comp for the duration of the test, because the Robot keyPresses, etc., will then start happening in the application which has focus at the time, not in the app which you are subjecting to testing...
Even if you precede every such Robot command with requestFocus or some such this is not a solution for the simple reason that between such commands, which must be run in the EDT, and the Robot's command, which must be run in a non-EDT thread, you may happen to do sthg (keyboard or mouse action) which will transfer focus outside the test app.
I think therefore that a Robot which knows it must interact only with the test app is kind of essential. Without that you "lose" your machine for the duration of the tests.
Running the tests in a VM might be one solution - does anyone know of any other?

Open Eclipse View in RCP headless mode?

I have headless (CLI) RCP app, normally handling command line options, but i'd occasionally need to show parts of the a gui anyway.
Is there a way to open a view part standalone(detached is fine) when PlatformUI/Workbench is not running?
WorkbenchPage.showView(the one I'd normally use to open the view) normally throws "workbench is not running" exception, which is expected of course in headless mode.
Is there some reasonable hack to do this? I tried running the RCP workbench with the event loop - the problem is that it's blocking execution and it seems too heavyweight.
I know I can create new Shell embedding the widget of the view, for it but then I'd miss the toolbars/menus that come with the proper view.
All the UI code is completely dependent on the workbench running. The workbench must be started with PlatformUI.createandRunWorkbench. So it is not possible to show a UI without doing this.
The simple SWT only Shell seems the easiest way.
Exclude the concept of RCP, and work with SWT/JFace components only.
Build some factory methods that simulate PlatformUI.createandRunWorkbench. Instead, they will create Shells and run the event loops themselves.
To me, this seems like a bit of an overkill if the app is going to be large. It it's not THAT enterprise-ish, then I guess you could do without the workbench framework. Be careful for dangling resources, though.

Debugging in NetBeans without changing focus

I have a program which uses the Robot class in Java to automate a bunch of keypresses and clicks. The problem I am encountering is not being able to set breakpoints on certain methods to debug because the focus would change when I skip to the next expression.
Is there a way I can bypass this by changing the default continue hotkey (F8) in NetBeans to a low-level keyboard hook that will check system wide?
The reason for this is because the macro I am designing runs too fast for me to see each action occurring. If I set breakpoints along the program, I must alt-tab to the IDE and continue to the next breakpoint, which, unfortunately, interferes with the macro.
If you need to interact with the system in a way that interferes with your program, you must separate your debugger from your program.
In other words, run the two on separate machines and do a remote debug from one machine to another.
The easiest way to do so if you don't have or want to use two machines, is to run your program in a virtual machine. A cheap solution is to use vmware player along with a Linux distribution supported by Netbeans.

Can I use java.awt.Robot from within a daemon?

I have written a server in Java that allows clients connected to it to control the mouse and keyboard of the computer. To do this it uses the java.awt.Robot class.
I need this server to run in the background and start automatically. The first OS I am tackling this problem on is Debian based (Ubuntu 11.04) and a daemon seems like the obvious choice. The problem is that when the daemon is started during boot or during the installation of my debian package (whose postinst script starts it using /etc/init.d/pc-remote-server start) I get this error:
java.awt.AWTException: headless environment
at java.awt.Robot.<init>(Robot.java:97)
at com.se.pcremote.server.CommandExecuter.<init>(CommandExecuter.java:72)
at com.se.pcremote.server.PCRemoteServer.<init>(PCRemoteServer.java:215)
at com.se.pcremote.server.PCRemoteServer.main(PCRemoteServer.java:122)
Is there any way I can use the java.awt.Robot class from within a daemon process? Could I spawn a secondary process from the daemon process that is not a 'headless environment'? Or is there a better way for me to get a 'service' like result that does not have this limitation?
"Headless" means that this code needs access to a graphics environment, and it hasn't.
You can run in headless mode by supplying a system property which provides a crude implementation which gives just the basics for running applications, but which most likely cannot support Robot. Try it however first.
If you cannot do that, you need a graphics environment for your process. The usual way to do this is to run a VNC X-server as it doesn't require physical hardware, and then connect to it.
I assume, you must set the DISPLAY variable correctly (in the environment of the robot process at the time when the robot process is started) for this to work -- in your case you would need to specify a display in your DISPLAY variable which is created some time after the program is started. --
No idea whether this really works, but you could give it a try and report back here whether it works.
Alright, after doing some more research and trying some more options here is what I came up with:
Can I use java.awt.Robot from within a daemon? No.
Further down in my question I elaborated a little:
Is there any way I can use the java.awt.Robot class from within a daemon process? No. As above.
Could I spawn a secondary process from the daemon process that is not a 'headless environment'? Not that I could figure out. It was going to be a lot of work if I did do it anyway.
Or is there a better way for me to get a 'service' like result that does not have this limitation? Yes! Use the desktop environment! In my case since I was using Ubuntu the desktop environment was Gnome. Gnome has a Startup Applications feature that runs off .desktop files on a global and per-user basis as described here. They also provide information on the structure of these .desktop files here. I added a .desktop file to /etc/xdg/autostart (the global autostart folder) that ran my Java 'service' and it worked like a treat.

Fake X11 display?

I have a Java program using AWT which I would like to run on a headless system. The display for the program does nothing other than display stats. When the program finishes, it exits. There is no user interaction on the display. The program creates an output file which I use in my build system.
Is there a way to get the Java program to run without an X11 display configured? Can I force Java to run the program without trying to display anything? I do not have access to the source code (it is just .jar file), so I can't make modifications to the source.
Any thoughts on how I could get this to work?
The underlying question here is how to run Java applications without an X server; providing a "fake" X server is only one option. In Java 1.4 and up, you can do the following:
java -Djava.awt.headless=true
This allows applications which use AWT to run on headless systems even without an X server.
Xvfb can do what you ask for. I've not used it myself, but here is a link to wikipedia: http://en.wikipedia.org/wiki/Xvfb
You can use a vncserver.
vncserver :1001
export DISPLAY=localhost:1001
java..
The added advantages is that you can actually view the gui
using vncserver 'just in case'
Could also run Xvnc in a low resolution and color depth.
As mentioned by Charles Duffy the traditional method is to tell Java to go headless.
Note that you can always mount the jar in Eclipse and use jad+jadclipse to see what it actually does, and perhaps even override a class if you need to by putting another class-file in "front" of it in the classpath.
A facility that might be relevant if the program uses Java2D is that newer Java versions use optimizations in the X11 server to render faster. This alone might be a reason to devote an X11 server attached to a high performance graphics card to your graphics processing.
I've used with great success in the past the PJA libraries, they don't seem to be maintained anymore, but then again, just just want to run...
I was able to get headless mode in OpenJFX with the command line arguments
-Dglass.platform=Monocle -Dmonocle.platform=Headless -Dprism.order=sw

Categories