Is it possible to click a Flash button via Javascript?

douglasb

Diamond Member
Apr 11, 2005
3,157
0
76
I am working on a project that has been in development for several months before I started working at my current place of employment. This particular project is an ASP .NET (VB) web application, and the main functionality of the site requires the user uploading an image file and performing various edits on it.

For whatever reason, whoever wrote the code for the upload process decided to use SWFUpload, which is basically a Flash file upload with a Javascript wrapper. The main reason behind them using Flash was so that a progress bar could be displayed with the % of the file that has been uploaded so far. I know that this same sort of thing can be done through AJAX, but it requires a bit more work (GMail's upload is an example of how this should have been done, but I digress...) To make matters worse, this Flash object is instantiated by Javascript in the window.onload of the page, so it doesn't even exist in the DOM at first.

At this point, the SWFUpload parts are pretty much here to stay, as replacing it with AJAX isn't practical and would be WAY too time-consuming. Trust me, that was my first idea, but it would require basically rewriting the entire application and scrapping several months of other developer's work.

My dilemma is this: I am currently writing tests in Visual Studio 2010 Ultimate (Web Performance tests, Load tests, and Coded UI tests). This one particular page (which happens to be the meat-and-potatoes of the entire application) will not pass any test I have recorded or written for it thus far. I have had the most success approaching it with a Coded UI Test, so that's what I am trying to do now. Typically what happens is that once I get to the page with the Flash file upload, the testing framework can't "see" the upload button on the Flash object (probably because it doesn't exist yet at this point) and the test comes to a grinding halt. If I manually click the button using my mouse, the rest of the test completes, but this one Flash object has all but made automated testing impossible.

After doing some digging around, I think I am on the path to a solution. In my testing project, I have added code where I can run Javascript functions from within my tests at-will (Visual Studio does not support this "out of the box", for whatever reason). As long as the function is in the same page that I am testing, it will run fine. What this means, though, is that I can't do anything on .load or using a similar method, because I only want the Javascript to run from my tests (and not during a normal page visit).

I have written Javascript to find the Flash object's "upload" button, but have so far been unsuccessful in getting Javascript to click it. A simple .click() does not work on this object like it does on normal HTML controls. My next idea is to try something like this:
Code:
function simulateClick(target) {
        var evt = document.createEvent("MouseEvents");
        evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        var cancelled = !target.dispatchEvent(evt);
        if (cancelled) {
            //alert('cancelled');
        } else {
            //alert('not cancelled');
        }
    }

and hopefully that will get the click where it needs to go. I am hearing that this may not be possible, however, due to a security measure added to Flash 10 and above. Does anybody know if this will work? Unfortunately, I can't test it right now, because the page that I need to put this on is currently checked out in Source Control (and it is checked out 90% of the time, as it is the main functionality for this application). Brilliance all around over here, I tell ya...This isn't the first time laziness/poor decisions at design-time have led to problems like this. Very frustrating, especially for a new guy like me.

Does anybody know if this will work, or have any other ideas? My boss has been pretty gung-ho lately about "doing things the Microsoft way" and having lots of code-coverage, testing, etc. I'm pretty sure "the Microsoft way" doesn't involve using Flash all willy-nilly because you're too lazy to write a proper AJAX upload widget, but there's no point telling them that at this point. Basically I need to find a way to make this test work, or just scrap testing for this entire project.
 

Ken g6

Programming Moderator, Elite Member
Moderator
Dec 11, 1999
16,835
4,815
75
I know from experience that Flash is nearly impossible to test. If there were a way to test it with Javascript, I'm sure the Selenium project would have figured it out by now. (Well, there is a way to test it with Selenium, but it requires recompiling the Flash object from its source, with certain debugging symbols.) The only software I know of that can even marginally test Flash (without that recompiling bit) is HP Quick Test Professional.

I WSH I could be more helpful, but I really don't know how Visual Studio tests work. (Can you convince VS to run a WSH script that sets the browser size and then clicks a pre-defined spot?)

Otherwise, the only other approach I know of would be low-level. I see you mentioned this in your previous thread. Can you find some way, potentially outside the MS stuff, to GET the web page, parse out the GUID, and POST the file? A script using curl could do this; so can SoapUI and HP LoadRunner.
 

DaveSimmons

Elite Member
Aug 12, 2001
40,730
670
126
Without modifying the source for the Flash object I don't think it's possible.

The UI in Flash is not built with HTML controls or part of the DOM so script commands have no effect.

The UI inside the Flash applet doesn't use standard Windows controls either so you can't use Win32 windows API code and messages.


> (Can you convince VS to run a WSH script that sets the browser size and then clicks a pre-defined spot?)

That should work as a hack -- generate a raw mouse click at the right x-y location. Just be sure to document that your tests will break with different page layouts, screen resolutions and possibly even new browser versions if the SWF screen location changes enough.
 
Last edited:

douglasb

Diamond Member
Apr 11, 2005
3,157
0
76
I WSH I could be more helpful, but I really don't know how Visual Studio tests work. (Can you convince VS to run a WSH script that sets the browser size and then clicks a pre-defined spot?)

Otherwise, the only other approach I know of would be low-level. I see you mentioned this in your previous thread. Can you find some way, potentially outside the MS stuff, to GET the web page, parse out the GUID, and POST the file? A script using curl could do this; so can SoapUI and HP LoadRunner.

I can do the suggestion at the top, but that's sort of a last resort. The boss was just bitching last week about people hard-coding things, but when they make horrible design decisions like this, it really leaves me no choice.

The 2nd suggestion almost works, but I have to use the GUID because the application stores the image file on the server side in a folder with that GUID in the name, then later retrieves the image (and flipped-x and flipped-y variations of it) so that the user can crop it and do various minor edits. I haven't tried this outside of the MS testing suite, and that really isn't an option. The boss has been on a kick lately about coding standards, using only the MS tools, etc.

Looks like I might have to just tell him that next time he wants functional testing and a high percentage of code-coverage, don't make the application entirely dependent on a Flash plugin that we didn't need in the first place.
 

Ken g6

Programming Moderator, Elite Member
Moderator
Dec 11, 1999
16,835
4,815
75
By "parse out" I meant store in a variable and use it later. LoadRunner, for instance, calls this "correlation".
 

douglasb

Diamond Member
Apr 11, 2005
3,157
0
76
By "parse out" I meant store in a variable and use it later. LoadRunner, for instance, calls this "correlation".

I'm going to try the other approach first, so I can actually test against the UI. My idea is to click an area relative to the Internet Explorer window. I think that can be done with the Windows API (user32.dll and such), but I don't know how I would go about it exactly, nor do I know how to do it through WSH. Any suggestions?