Monday, April 18, 2016

Mash Robot testing with HaxeFlixel!

I know I had said to stay tuned for certain coverage adventures.  I had an unexpected idea that took me on a wild tangent, on which I still am.  But the tangent involves HaxeFlixel and testing and scrollbars and all sorts of things.

So today's post is about creating a button-mashing robot to use for automated random stress testing, inspired by a post I saw on StackExchange.

I thought it would be fairly simple to do this in HaxeFlixel, since I had already delved into the VCR code to fix an issue with mouse event playback (the pull request hasn't been merged just yet, but I haven't had cause to change it yet, whenever I've used the updated version.)  It was.  Almost.  Well, it still was in the end, but took some more delving and debugging until I realized what was happening.

My first approach was to use the same approach I had taken with the VCR, and just go down a level into OpenFL and send input events there.  For various reasons, this didn't have the effect I had intended, but I won't go into them here.

So my next course of action was to leverage the VCR playback code itself (beyond just my sometimes-OpenFL-calling workaround), to keep things more integrated with HaxeFlixel's update flow.  This seemed to work on the keyboard end of things, but not with the mouse.

Where I ran into trouble is that I wanted my masher robot to work a bit differently than the VCR setup in flixel, but I hadn't acknowledged this difference enough when analyzing why it wasn't working.  The difference was that with the normal VCR, either you're recording, or you're playing back, never both.  My masher robot, OTOH, I wanted to pretend to be playing back, while still recording so that if the robot managed to crash my game, I had a way of reproducing it later.

Once I had this figured out, I saw that thankfully, HaxeFlixel makes it easy to override the spot where it would normally (when recording) update the mouse position using data from OpenFL (from the DisplayObject class, in the form of the FlxG.game instance.)  All I had to do was make a simple new class derived from FlxMouse, override its update() with everything except the top portion that calls setGlobalScreenPositionUnsafe(), and then replace it in my Main.hx like so:

FlxG.inputs.replace(FlxG.mouse, new MashMouse(FlxG.mouse.cursorContainer));

With that, everything worked great.  I now have a robot that sometimes clicks entirely randomly, usually clicks a random FlxObject, and presses random buttons, all the while recording everything it does.

If there's interest, I could package and release this later, as I think it can be a useful testing tool.