Wednesday, June 27, 2012

iMacros - Logging Errors and Taking ScreenShots

Recently, I got a chance to work on and use a wonderful automated testing tool - iMacros [thanks to my friend Abhinav who kept giving me more and more requirements to program with this tool]. Specifically I used iMacros as a plugin in firefox for testing web pages. I must admit, the folks @iMacros have done a marvellous job and kudos to them for this.
In this blog post I want to specifically talk about one thing that stumped me most of the time using this tool - "How do I log the detailed HTTP error (500, 403 etc....) to a log file & how do I take a screenshot when such a thing happens?". Here's how I did it:

Saving a ScreenShot


iMacros provides for a SAVEAS command, using which you can take and save an image of the page displayed in the browser. I created a new macro, takeScreenShot.iim and here is the implementation


VERSION BUILD=7401110 RECORDER=FX
SAVEAS TYPE=PNG FOLDER={{SCRSHOTFOLDER}} FILE={{SCRSHOTFILENAME}}

Pretty simple huh!! Exactly! The only thing to note here is that I am providing the FOLDER and FILE values from {{SCRSHOTFOLDER}} and {{SCRSHOTFILENAME}} variables respectively. You can hard code the values if required, but I am not sure if it would be useful to hardcode the file name.
To send variables from outside to this macro you can use the iimSet command and set the values appropriately. Also, iMacros can only save files as png, so I always include "png" as an extension in the filename that I pass in to this macro.


To use this macro, simply call it from the place you want to take the screenshot (use iimPlay command).


Logging Errors
This one is a bit tricky. There are two parts to this that I tried to do:
1. Log the faulting Url and the time stamp
2. Log the faulting Url, timestamp and detailed error message

The first one turned out to be easy. Here is some js code to do this
var ret = iimPlay(<your macro name>);
if(ret != 1)
{
        var today = new Date();
      var dd = today.getDate();
      var mth = today.getMonth() + 1;
      var year = today.getFullYear();
      var hrs = today.getHours();
      var mins = today.getMinutes();
      var secs = today.getSeconds();
      var ts = mth + "-" + dd + "-" + year + "  " + hrs + ":" + mins + ":" + secs;

var message = "\r\n" + ts + " FAILED URL: " + window.frames[3].location.href + "\r\n";

writeToFile(logFile, message);

}

I am not going to detail out the writeToFile method here. It is a simple method that takes in a file name and a message string to log and appends the message string to the end of the file.
The key thing to note here is the var ret = iimPlay(....) stuff. The iimPlay command returns a code that signifies the success/failure of the macro that it runs. A detailed list of error messages can be found here.
If the return code from iimPlay is not 1, then we know it's a failure and we can proceed logging stuff.
You might want to add the error code (in ret) to the message string, for a more detailed log.

This brings us to our next question, what if we also wanted to log all the text/html for the erroneous page? Some might argue here that instead of logging the text on the page, won't it be better if we just saved a screenshot instead? I agree, but there might be instances where you would want to send a log file across to the developer so that he can copy paste stuff from the same. Also, there might be some error info that might only be displayed when you expand the section containing that info. These kind of things cannot be easily done using a screenshot. So, here's how I implemented logging the text:

First, we need a way to extract text of a web page. Here is a snippet that can be used to achieve this:

TAG POS=1 TYPE=HTML ATTR=* EXTRACT=TXT

Paste this snippet at the end of the macro that displays the web page you are testing.
Then, in the js code, you can use the iimGetLastExtract() command to get the extracted html of the web page.

var err_string = iimGetLastExtract();
Once we have this, it should be easy to log it to a file, right! But there is a catch.... iimGetLastExtract() does not return back extracts if the web page displayed is the result of an HTTP error (or if iimPlay's return code is something other than 1). To get around this issue, I did a small hack (which apparently I don't like, but did not have any other way of doing it as of this writing), wherein I included the following snippet in my macro that displayed the web page:

SET !ERRORIGNORE YES

Once you do this, iimPlay will always return 1 because it would ignore all the errors. That brings us to the next stumbling block:
our js code if(ret != 1), will not work anymore for detecting errors. To get around this, did the following:


     var err_string = iimGetLastExtract();
     if(err_string.indexOf("Server Error in")> -1)
     {
            //log timestamp and err_string here

     }

Although this does not look very efficient and neat, but for now it gets the job done for me. You can add more conditions to the if (just like the one for "Server Error in") for the errors that you expect to log and it should work the same.

That's it for this post. Hope this helps someone who needs it.

Happy web testing!!
Make Custom Gifts at CafePress

No comments:

Post a Comment