Monday, August 16, 2010

Selenium methods for extracting elements

I have been working off late in automating web testing using the selenium framework. Not to mention there are handy generic methods to extract all links etc but sometimes one might need a bit more fine grained result than that. This post is some of the methods we implemented that extend to such functionality

We use TestNG and selenium java client driver for our tests, I am skipping the details of common helper methods session() that opens a link in selenium session, you can find it in the selenium-grid distribution. Here's a
method to check if all images present in the page are visible.
public void testAllImagesAreVisible() throws Exception {
 int nImages = Integer.parseInt(
session().getEval("window.document.images.length;"));
 LOGGER.debug("found images :::" + nImages);
 for (int i = 0; i < nImages; i++) {
   session().isVisible("dom=window.document.images[" + i + "]");
 }
}

the method finds the number of images in a page; and then lopps through them running the isVisible check. You might come across situations where you want to extract all links within a div; instead of the getAllLinks that does it for the entire page. Here's a way to do that.
public String[] getAllLinksWithinDiv(String divID){
 String domLocator = "dom=window.document.getElementById('"+
divID+"').getElementsByTagName('A')";
 ....
You can then store all link texts in a array for further use (clicking through all of them for example)
int nAnchors = Integer.parseInt(session().getEval(domLocator + ".length"))
String sArray[] = new String [nAnchors];
...
    sArray[i] = session().getEval(domLocator + "[" + i + "].text");
...

Thats about it.

Tuesday, March 30, 2010

Extracting Log Messages on category

I was recently faced with this question of how to ease out log analysis for our production system. We run a cluster of sorts with applications running on 4 tomcat fronts. The site in question has requests/day going into millions. So, it is not a surprise the there is a flooding of logs. It gets really tough to monitor logs to see what's for example the highest occurring WARN messages if you end up logging 400 MB of log statements per hour.

So I came up with script that might help you as well if you are looking for some quick filtering of logs.

We have the following log format

{DATE} {TIMESTAMP} {LOG_LEVEL} {MESSAGE} | {LOGGING COMPONENT} {TOMCAT-HTTP-PROCESSOR}

here's the script:

use Getopt::Long;
GetOptions("file=s","level=s");

$w = "(.+?)";

if($opt_file){
$DISTILLED_LOGFILE = "distilled-".$opt_level."-".$opt_file;
open(INPUTFILE, "$opt_file") or die("Could not open log file.");
open OUTPUTFILE, ">", $DISTILLED_LOGFILE, or die("Could not create filtered log file.");
foreach $line () {

 $line =~ m/^$w $w $w $w \| $w \[$w\]/;
 $date = $1;
 $timeStamp = $2;
 $logLevel = $3;
 $message = $4;
 $classLocation = $5;
 $httpProcessor = $6;

 if($logLevel eq $opt_level) {
  print OUTPUTFILE "$logLevel\t$message\t$classLocation\n";
 }
}

close(INPUTFILE);
close(OUTPUTFILE);

}else {
  print STDOUT "You didn't select a file!\n";
};

This is how to use it

filter_logfile.pl -file someTomcatlogFile -level logLevel

What it does is pretty simple. matches each line for a regex pattern, checks if the line is the same log level as provided by you on command line; if yes. it copies the Log Level; Message and the component logging the message to a new file named distilled-LOGLEVEL-[YOUR-INPUT-LOG-FILE-NAME].

Happy Log filtering!