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:
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.
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.
