package Test::AutomationFramework; 
use 5.012003;
use strict;
use warnings;
use Date::Manip;
use File::Path;
use Test::More;
use Getopt::Long;
use File::Copy;
use File::Find;
use Cwd;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw(
) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw(
help
processTCs
processTC
processProperty
genDriver
initTAF
);


our $VERSION = '0.058.14';   	

###################### TAF Global Variables ###############################
	my %tsProperty;my %tafProperty; my $propertyOp='';	my $regression=0; my $help=0; my $sleep4Display = 0; my $notUsegetTCName= 0;
	my $tcIdCtr=0; my $ip = 'localhost'; my $tsDriver = "null"  ;	 # cmd-line-overwrite $testDriverName (generated by -e .. index.pl or index.ps1)
 	my $pr2Screen = 1; my $tcIdMin= 0; my $reportHtmlSummaryStr = ''; # String for mouse-over display TC summary
	my $Execution_24_7	= "n";
	my $NofExecution	= "1"; my $NofExecutionCtr=0;
	my $ExecutionLength	= "10000 hour";
	my $ExecutionType 	= '>'; 
	my @tcDesc;		 my $tsFilter=".*";

###################### TAF Generated Variables ###############################
	my $scriptName 			= $0; $scriptName =~ s/\\/\\\\/g; 
	my $workingDir			= getcwd(); 

###################### TAF Default Variables ###############################
	my $interact 			= "n";
	my $tcPropertyPatternName 	= "tcRunResult";
	my $tcPropertyPatternPattern 	= ".*"; 
	my $tcNamePattern		= "TC*"; 		
	my $tcOp			= 'list';	
	my $c				= "c:";
	my $taf				= "taf.pl";
	my $SUTSymbol			= "_";
	my $tsFilterDefault 		= "_";
	my $_TAF			= "_TAF";
	my $SvrDrive 			= $c.'/'.$_TAF; 
	my $SvrProjName 		= '_testSuit_'; 
	my $SvrTCName 			= '_testCase_';
	my $SvrTCNamePattern 		= "*"; 
	my $SvrPropNamePattern 		= '.*';
	my $SvrPropValuePattern 	= ".*";
	my $SvrTCNameExecPattern 	= ".".$SvrTCNamePattern;
	my $SvrLogDir 			= ''.$SvrProjName.'';
	my $ps1_args 			= "";  
	my $exitTAFGracefullyLock   	= $c.'/'.$_TAF.'/'."_exitTAFGracefully_.txt";
 	my $performanceMode		= "slow4webUI"; # fast4cmd
###################### TAF WebUI Default Settings ###############################

	my $web_ui_title		="Test Automation Framework"; 
	my $webUI_TCDescWidth 		= 80; 
	my $scrollAmount		= 0; 
	my $borderWidth			= 0; 
	my $borderStyle			= "SOLID"; 
	my $passFailDisplayWidth	= 10; 
	my $maxPassFailDisplayWidth	= 20; 
	my $reportHtmlSummaryScale 	= 3600; 				# in seconds
	my $reportHtmlSummaryScaleMajor = 12; 					# in seconds
	my $tsProperty    		= 'tsProperty.txt';

	my $reportHtml  		= 'index.htm';
	my $reportHtml1 		= '_tcReport_.html';
	my $reportHtmlHistory		= '_tcReportHistory_.html';
	my $reportHtmlSummary   	= '_tcReportSummary_.html';
	my $tc_pl			= "tc.pl";

	my $reportHtml_http  		= 'index_http.htm'; 			# $reportHtml."_http";
	my $reportHtml1_http 		= '_tcReport_.html'."_http";
	my $reportHtmlHistory_http	= '_tcReportHistory_.html'."_http";

	my $url 			= 'file:///'.$SvrDrive;  
	my $urlHttp			= 'http://'.$ip.'/'.$_TAF;



sub new { my $package = shift;
	return bless({}, $package);
}

sub tcLoop {
	my $returnValue; &releaseExitTAFGracefullyLock(); 
	while (($Execution_24_7 eq 'y') || ($NofExecution > $NofExecutionCtr)) {
		$NofExecutionCtr++;
	if ($pr2Screen == 1) {
		if (($NofExecution == 1) && ($Execution_24_7 ne 'y')){; 
		print "Processing ......\n" ; 
		} else {		
		print "Processing ($NofExecutionCtr\/$NofExecution) ......\n" ; 
		}
	
	} else { print "";}
		if (($propertyOp =~ /^\s*$/) || ($propertyOp =~ /tcDescAuto/i)) {&tcPre(); &tcMain_(); &tcPost(); }
		else { &tcMain_(); } # TC Property Process
	if ($pr2Screen==1) {print " - Completed -\n"; } else { print "";}
	}
	return $returnValue;
}
sub tcPre {
 	if (-e $SvrDrive.'\\'.$SvrProjName) {;} else { print "$SvrDrive/$SvrProjName doesn't exist.\n"; exit; }
	##################### PrePRocessor #####################
 	&createFile_($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1,"");
 	&createFile_($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtmlHistory,"");
 	&appendtoFile_($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtmlHistory,"<html><body><pre>\n");
 	&createFile_($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1_http,"");
	########################################################
}

sub tcMain_ { $notUsegetTCName= 1; find(\&recursiveSearchtcMain, $SvrDrive); }
sub recursiveSearchtcMain() { 
	my $returnValue ='';
	if ($SvrTCNamePattern eq '*') { $SvrTCNamePattern = '.*';} 
	if (($File::Find::name =~ /tc.pl\s*$/) && ($File::Find::name =~ /$SvrDrive\/$SvrProjName\//i) && ($File::Find::name =~ /$SvrTCNamePattern/i))  # TC Filter
	{	
		if (&detectExitTAFGracefullyLock() =~ /\bLocked\b/i ) { print "TAF exited gracefully\n"; exit; } 
		$tcIdCtr++;
		my $eachTC = &getRoot($File::Find::name);	
		$SvrTCName = &getDir($File::Find::name);
		$eachTC = &getRoot($eachTC);

		&getWeb_($eachTC) =~ /scrollAmount\s*=\s*(\d+)/; $scrollAmount = $1; if ($scrollAmount) {;} else {$scrollAmount =0;}
		&getWeb_($eachTC) =~ /borderWidth\s*=\s*(\d+)/ ; $borderWidth  = $1; if ($borderWidth) {;} else {$borderWidth=0;}
		&getWeb_($eachTC) =~ /borderStyle\s*=\s*(.+)/  ; $borderStyle  = $1; if ($borderStyle) {;} else {$borderStyle=0;}

		my $tmp = $tcOp;

		if (($tcOp !~ /^\s*$/)&&($SvrTCName =~/$SvrTCNameExecPattern/)&&($tcIdCtr >= $tcIdMin) && 
			( &getProperties(&getTCName($SvrTCName) , $tcPropertyPatternName, "value") =~ /$tcPropertyPatternPattern/i))  { 		# Property/testcaseExec Filter
		   if ($propertyOp) {								# Property Processor
		        ##################### Property OPeration Start ####################
			if ($propertyOp =~ /tcDescAuto/) {					# add tcDesc when generatTestsuite
				my $tcDescAuto="";
				if ($#tcDesc eq 0 ) {;} else { $tcDescAuto = "add=tcDesc:".shift @tcDesc; }
				my $tcDescAuto_ = $tcDescAuto; $tcDescAuto =~ s/_space_/ /g; $tcDescAuto =~ s/_column_/:/g; $tcDescAuto =~ s/_eq_/=/g; 

				printf "%-20s %s %s\n", "processProperty:", &getTCName($File::Find::name),$tcDescAuto;
				&processProperty("",&getTCName($File::Find::name), $tcDescAuto_);

			} elsif (($propertyOp =~ /_doit_/i) || ($propertyOp =~ /^\s*_?get_/i)) {   					# property Operation (_doit_)
				my $propertyOp_  = $propertyOp; 
				$propertyOp_  =~ s/_doit_//g;
				my $rst = &processProperty("",&getTCName($File::Find::name), $propertyOp_);
				print "$File::Find::name:    $propertyOp = $rst\n";
			} else {
				print "[TS/TC=$File::Find::name]  propertyOp=$propertyOp    _doit_\n"; # property Operation (print it)
			}
		        ##################### Property OPeration End   ####################
		   } # else 
		   if (($propertyOp =~ /tcDescAuto/i) || ($propertyOp =~ /^\s*$/)) {		# TC Exec Processor
			##################### TC Operation Start ######################
			if ($scrollAmount ==0 and $borderWidth ==0) { 					  # TC Execution
				&updateWeb_(&getDir($File::Find::name),1, $borderWidth, "SOLID", $ExecutionType);
				if ($performanceMode =~ /slow4webUI/i) { &updateTestsuitePassFail ()	;}
				$returnValue = $returnValue. &processTC("","$tcOp=$eachTC",$pr2Screen)."\n"; 
				if ($performanceMode =~ /slow4WebUI/i) {
				&logTC($eachTC);						# TC Logging	  -> tesesuite\testcase\_tcLog.html
				&reportTCHistory($eachTC);					# TC ReporHistory -> testsuite\_tcReportHistory_.html
				&reportTCSummary ();
				&updateTestsuitePassFail ()	;
				}
				&updateWeb_(&getDir($File::Find::name),0, $borderWidth, "SOLID");
				if (($tcOp !~ /list/) && ($tcOp !~ /mark/)) {sleep $sleep4Display;}
			} elsif ( $scrollAmount != 0 ) {								# Handle different TC exec state
				if       (($scrollAmount != 0 and $borderWidth== 0 )) { $borderWidth = 1; $borderStyle = "DOTTED"; }
				elsif    (($scrollAmount != 0 and $borderStyle =~ /DOTTED/i)) {$borderWidth =1; $borderStyle = "SOLID"; }
				elsif    (($scrollAmount != 0 and $borderStyle =~ /SOLID/i)) {$scrollAmount=0; $borderWidth =0; $borderStyle = "SOLID"; }
				if ($performanceMode =~ /slow4WebUI/i) {
				&logTC($eachTC);						# TC Logging	  -> tesesuite\testcase\_tcLog.html
				&reportTCHistory($eachTC);					# TC ReporHistory -> testsuite\_tcReportHistory_.html
				&reportTCSummary ();
				&updateWeb_(&getDir($File::Find::name),$scrollAmount, $borderWidth, $borderStyle);
				}
			} ##################### TC Operation End ######################
		   } 

		}

		$scrollAmount = 0; $borderWidth = 0; $borderStyle = "SOLID";
		#}	# Property Filter 							# Passing $scrollAmount, $borderWidth, $borderStyle, 
	} # TC Filter
}
sub tcPost {
	##################### Post PRocessor ###################
 	&appendtoFile_($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtmlHistory,"</pre></body></html>\n")				;
   	&mergeFile_($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml, $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1)		;
   	&mergeFile_($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml_http, $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1_http)	;
	&prHtml1()			;
	&appendtoFileFile_($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1,      $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml)	;
	&appendtoFileFile_($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1_http, $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml_http);
	&prHtml2()			;
	&generateRootIndex       ()	; 
	&updateTestsuiteHTA      ()	;
	&updateTestsuitePassFail ()	;
	########################################################
} 


#######################generateRootIndex {
sub scanTestsuites {					######### generate index.htm
	shift; my $doit="n"; 
	if ($tsFilter =~/_doit_/i) { $doit='y'; $tsFilter =~ s/_doit_//i;} 
	#my @dir = glob "${c}\\${SUTSymbol}*"; 
	my @dir = glob "${c}\\${$tsFilterDefault}*"; 
foreach my $each (@dir) {
	$each =~ s/\\/\//g;
find(sub { if (($File::Find::name =~ /index\.\w+$/i) && ($File::Find::name !~ /${c}\/${_TAF}/i)) {
			my $dirName =  $File::Find::name; $dirName =~ s/[\\|\/]index..+$//g;
			if ($dirName =~ /$tsFilter/i) {
			my $cmd = sprintf "$SvrDrive/$taf workingDir=$dirName;web_ui_title=$dirName;generateTestsuite" ;  
			print "$cmd\n"; if ($doit =~ /\by\b/) { print "Running ...\n"; $cmd =~ s/\//\\/g; my $rst = `$cmd`; print $rst."\n";}
			}
		}
	 }, $each);
}
	1;
}

#######################generateRootIndex {
sub generateRootIndex {					######### generate index.htm
		&readTAFProperty(); # read %tafProperty;
	#### part 1 ####
open INDEX, ">$SvrDrive/index.htm"; 
print INDEX<<EOF;
<html><pre>
<h2>Automated Test Suites on $ip</h2>
<ul>
EOF
find(sub { if ($File::Find::name =~ /index\.htm$/i) {
			my $tmp= $File::Find::name; 
			my $tmp2 = $File::Find::name; 
			$tmp=~ s/$SvrDrive//;
			$tmp2 =~ s/\/index.htm//g;
			if ($tafProperty{$tmp2} ) { $tmp2 = $tafProperty{$tmp2}; } 
			print INDEX "<li><a href=\"$url".$tmp."\">$tmp2</a>\n" if ($tmp ne "/index.htm");
		}
	 }, $SvrDrive);

print INDEX <<EOF;
</ul>
</pre></html>
<style type="text/css"> a { text-decoration:none} </style>
EOF
;
close INDEX;
	#### part 1 ####
	#### part 2 ####
open INDEX, ">$SvrDrive/index_http.htm";		########## generate index_http.htm 
print INDEX<<EOF;
<html><pre>
<h2>Automated Test Suites on 10.24.2.66</h2>
<ul>
EOF
find(sub { if ($File::Find::name =~ /index_http\.htm$/i) {
			my $tmp = $File::Find::name; 
			my $tmp2 = $File::Find::name; 
			$tmp =~ s/$SvrDrive//;
			$tmp2 =~ s/\/index_http.htm//g;
			if ($tafProperty{$tmp2} ) { $tmp2 = $tafProperty{$tmp2}; } 
			print INDEX "<li><a href=\"$urlHttp".$tmp."\">$tmp2</a>\n" if ($tmp ne "/index_http.htm");
		}
	 }, $SvrDrive);

print INDEX <<EOF;
</ul>
</pre></html>
<style type="text/css"> a { text-decoration:none} </style>
EOF
;
close INDEX;
	#### part 2 ####
}

####################### read Testsuite web_ui_title
sub readWebTitle{ 
	my $dir = shift;  my %prop; my $webTitle = "Test Automation Framework";
	if (-e "$dir/tsProperty.txt") {
		open Fin, "$dir/tsProperty.txt"; 
		while ($_ =<Fin>) {
			my $tmp=""; /(\s*)/; $_ =~ /^\s*(.+)\|/       ; $tmp = $1; $prop{$tmp}=$_; 
			if ($_ =~ /web_ui_title\s*:\s*(.+)\s*:\s*web_ui_title/) {$webTitle = $1;}
		} close Fin; 
	}
	return $webTitle;
}

####################### get Testsuite Total Exec Time 
sub getTestsuiteTotalExecTime {
	my $index= shift; my $index_; my $tsTotalExecTime = 0;
		if (-e $index) {
		open FinTS, $index; 
		while ($_ = <FinTS>) { if ($_ =~ /^\s*<li\s+style="color:/i) { $_ =~ /(\d+)\s*\(s\)/; $tsTotalExecTime = $tsTotalExecTime + $1;} }
		close FinTS;
		} 
	return &timeConvert($tsTotalExecTime); 
}

####################### get Testsuite Total Exec Time 
sub timeConvert {
	my $totalTime = shift; 
	my $hr  = int ($totalTime/3600); 
	my $min = int (($totalTime - $hr*3600) / 60);
	my $sec = int (($totalTime - $hr*3600 - $min * 60));
	$totalTime = sprintf "%02d:%02d:%02d",$hr,$min,$sec;
}

#######################generateFailedTCHtml {
sub createTestsuitePassFailedHtml {
	my $index= shift; my $index_;

	####################### failed.htm #####################
	if ($index=~ /index\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_failed\.htm/;
		if (-e $index) {
		open Fin, $index; open Fout, ">$index_";
		while ($_ = <Fin>) {
			if ($_ =~ /tcPropertyPatternPattern/) { $_ =~ s/tcPropertyPatternPattern=\.\*/tcPropertyPatternPattern=fail/g; }
			if ($_ =~ /RunFile/) { $_ =~ s/index\.htm/index_failed\.htm/g; }
			if (&getLatestPassFail($_) =~ /color:gray;/i) { ;
			} elsif (&getLatestPassFail($_) =~ /color:green;/i) { ;
			} else { 
				print Fout $_; }
			}
		close Fout; close Fin;
		}

	} elsif ($index=~ /index_http\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_failed\.htm/;

		if (-e $index) {
		open Fin, $index; open Fout, ">$index_";
		while ($_ = <Fin>) {
			if (&getLatestPassFail($_) =~ /color:gray;/i) { ;
			} elsif (&getLatestPassFail($_) =~ /color:green;/i) { ;
			} else { print Fout $_; }
		}
		close Fout; close Fin;
		}
	}	
	####################### failed.htm #####################

	####################### pass.htm #####################
	if ($index=~ /index\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_passed\.htm/;

		if (-e $index) {
		open Fin, $index; open Fout, ">$index_";
		while ($_ = <Fin>) {
			if ($_ =~ /tcPropertyPatternPattern/) { $_ =~ s/tcPropertyPatternPattern=\.\*/tcPropertyPatternPattern=pass/g; }
			if ($_ =~ /RunFile/) { $_ =~ s/index\.htm/index_passed\.htm/g; }
			if (&getLatestPassFail($_) =~ /color:gray;/i) { ;
			} elsif (&getLatestPassFail($_) =~ /color:red;/i) { ;
			} else { 
				print Fout $_; }
			}
		close Fout; close Fin;
		}

	} elsif ($index=~ /index_http\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_passed\.htm/;

		if (-e $index) {
		open Fin, $index; open Fout, ">$index_";
		while ($_ = <Fin>) {
			if (&getLatestPassFail($_) =~ /color:gray;/i) { ;
			} elsif (&getLatestPassFail($_) =~ /color:red;/i) { ;
			} else { print Fout $_; }
		}
		close Fout; close Fin;
		}
	}	
	####################### pass.htm #####################
	####################### other.htm #####################
	if ($index=~ /index\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_others\.htm/;

		if (-e $index) {
			open Fin, $index; open Fout, ">$index_";
			while ($_ = <Fin>) {
			if ($_ =~ /tcPropertyPatternPattern/) { $_ =~ s/tcPropertyPatternPattern=\.\*/tcPropertyPatternPattern=\\\\d+_pipe_null/g; }
			if ($_ =~ /RunFile/) { $_ =~ s/index\.htm/index_others\.htm/g; }
				if (&getLatestPassFail($_) =~ /color:green;/i) { ;
				} elsif (&getLatestPassFail($_) =~ /color:red;/i) { ;
				} else { print Fout $_; }
			}
			close Fout; close Fin;
		}

	} elsif ($index=~ /index_http\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_others\.htm/;

		if (-e $index) {
			open Fin, $index; open Fout, ">$index_";
			while ($_ = <Fin>) {
				if (&getLatestPassFail($_) =~ /color:green;/i) { 
				} elsif (&getLatestPassFail($_) =~ /color:red;/i) { ;
				} else { print Fout $_; }
			}
			close Fout; close Fin;
		}
	}	
	####################### other.htm #####################
}

#######################generateFailedTCHtml 

sub getLatestPassFail {
	$_ = shift; my $color;
	if ($_ =~ /^\s*<span\s+style="color:black;">/) {
		if ($_ =~ /^\s*<span\s+style="color:black;">\s*<a\s+style="color:(\w+)">\*/) {$color = $1;} else {$color = "gray";}
	}
	if ($color) { return "color:$color;";} else {return "_";}
}

sub updateWeb {
	my  %tsProperty;
 	my $tcname = 'TC_tc1'; $tcname = shift if @_		;	
 	my $scrollamount = 0 ; $scrollamount = shift if @_	;
	$tcname = &getTCName($tcname); $tcname =~ s/\\/\//g	;

	if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml) {
 		open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml		;
 		open Fout, ">".$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_"	;
 		while ($_ = <Fin>) {
 			my $tcnameTmp = $tcname;
 			if ( $_ =~ /$tcnameTmp/i) {
 				$_ =~ /scrollamount=\s*(\d+)\s*/;
 				$_ =~ s/scrollamount=\s*$1\s*/scrollamount=$scrollamount/;
 			} 
 				print Fout $_;
 		}
 		close Fout;
 		close Fin;

  		move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml);
	}
	return "tcCtr_Dynamics=$scrollamount";
}

################################################################################
#        
################################################################################
sub updateTestsuiteHTA {
	open Fin, $SvrDrive."/index.htm" || die "Can't open index.htm";
	while ($_ = <Fin>) { chop; if ( /\/\/\/(.+)index.htm/ ) { my $ts= $1; &createTestsuiteHTA ($ts); } }
}

sub tsPostProcessPlugin {
	open Fin, $SvrDrive."/index.htm" || die "Can't open index.htm";
	while ($_ = <Fin>) { chop; if ( /\/\/\/(.+)index.htm/ ) { my $ts= $1; print "postProcessPlugin: $ts\n"; } }
}
sub updateTestsuitePassFail {
	if (-e $SvrDrive."/index.htm" ) {
	open FinIndex, $SvrDrive."/index.htm" || die "Can't open index.htm";
	while ($_ = <FinIndex>) { chop; 
		if ( /\/\/\/(.+index.htm)/ ) { 
			my $ts     = $1 ; &createTestsuitePassFailedHtml ($ts); 
			my $ts_http = $ts; $ts_http =~ s/index\.htm/index_http\.htm/; &createTestsuitePassFailedHtml ($ts_http); 
		} 
	}
	close FinIndex;
	}
}

sub createTestsuiteHTA {
	my $tsDir = shift; @_ = split /\//, $tsDir; my $testsuite = $_[$#_];
	&createFile_( $tsDir.'ts.hta', 
"
<html>
<head>
	<script language=\"JavaScript\">
		function RunFileHTTP(testsuite, testcase) {
//			alert(\"testsuite is \" + testsuite + \" testcase is \" + testcase );
			 WshShell = new ActiveXObject(\"WScript.Shell\");
		    	 cmd= '$c\\\\windows\\\\system32\\\\schtasks.exe /delete /tn TAF_'+ testsuite + ' /f'; 
			sleep (1000);
 //alert (cmd);
			 WshShell.Run(cmd, 1, false);
			 cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /create /TR \"$c\\\\$_TAF\\\\taf.pl testsuit='+testsuite+';testcaseExec='+testcase+';exec\" /TN TAF_'+testsuite+' /sc monthly /mo 1 /F'; 
			sleep (1000);
 //alert (cmd);
			 WshShell.Run(cmd, 1, false);
    		  	 cmd= '$c\\\\windows\\\\system32\\\\schtasks.exe /run /tn TAF_'+testsuite; 
			sleep (1000);
 //alert (cmd);
			 WshShell.Run(cmd, 1, false);
		}

	function sleep(milliseconds) {
	  var start = new Date().getTime();
	  for (var i = 0; i < 1e7; i++) {
	    if ((new Date().getTime() - start) > milliseconds){
	      break;
	    }
  	}
}

	</script>

</head>
<body onLoad =\"RunFileHTTP(\'$testsuite\', \'.*\')\">Run $testsuite\/ts.hta</button> <p>
</body>
</html>

")
;

}	

################################################################################
#        
################################################################################
sub initTAF {
	foreach my $each (split /\n/, `schtasks /query`) {
		if ($each =~ /TAF_/i) {
			$each =~ /^\s*(.+)\s+(\d+\/\d+\/\d+)\s+/;
			my $processName = $1; my $cmd = "schtasks /delete /tn $processName /f"; `$cmd`;
		}
	}
}

################################################################################
#        
################################################################################

sub readTestSuitProperty {
	if ( -e $SvrDrive.'/'.$SvrProjName.'/'."tsProperty.txt") {
	open Fin, $SvrDrive.'/'.$SvrProjName.'/'."tsProperty.txt";
	while ($_ = <Fin>) {
		chop;
		#	if ($web_ui_title =~ /Test Automation Framework/i) {
			# if ($_ =~ /web_ui_title\s*:\s*(.+):\s*web_ui_title/)  { 
 			if ($_ =~ /web_ui_title\s*:\s*(.+)\s*:\s*web_ui_title/)  { 
			$web_ui_title = $1;
			}
			# }
		my $tcname, my $tcdesc;
		($tcname, $tcdesc) = split /[\|]/, $_;
		if ($tcdesc) {
		$tcname =~ s/^\s*//; $tcname =~ s/\s*$//;  # $tcdesc =~ s/^\s*//;
		$tsProperty{$tcname}= $tcdesc;
		}
	}
	close Fin;
	}
}

################################################################################
#        
################################################################################

sub readTAFProperty {
	if ( -e $SvrDrive.'/'."tsProperty.txt") {
	open Fin, $SvrDrive.'/'."tsProperty.txt";
	while ($_ = <Fin>) {
		chop;
		if ($web_ui_title =~ /Test Automation Framework/i) {
 			if ($_ =~ /web_ui_title\s*:(.+):\s*web_ui_title/)  { 
			$web_ui_title = $1;
			}
		}
		my $tcname, my $tcdesc;
		($tcname, $tcdesc) = split /[\|]/, $_;
		if ($tcdesc) {
		$tcname =~ s/^\s*//; $tcname =~ s/\s*$//;  # $tcdesc =~ s/^\s*//;
		$tafProperty{$tcname}= $tcdesc;
		}
	}
	close Fin;
	}
}
################################################################################
#	Subroutine Name : logTC
#		Function: create TC _tcLog.html for each TC
#	Input Parameters: Test Case name
#	Output/Returns  : c:\inetpub\wwwroot\*.html
################################################################################
sub logTC {		# 	Update TC Log on webUI (TH:WebUI)
    my $currentTime  = &UnixDate( "now", "%m/%d/%Y %H:%M:%S %Z" );
    my $tcname       = shift; $tcname = &getTCName ($tcname);
	 if (&getTCLogFname($tcname) =~ /_tcLog\.txt\s*$/ ) { 
	    my 	$webLogText =  &readFile("$tcname\\_tcLog.html");
	       	$webLogText =~ s/<html>\s*<body>\s*<pre>\s*//;
	       	$webLogText =~ s/<\/pre>\s*<\/body>\s*<\/html>\s*//;
	       	$webLogText =~ s/\n/_nl_/g;
	       	$webLogText =~ s/\s*_nl_\s*/\n/g;
    		my $fileText = &readFile(&getTCLogFname($tcname)); # todo Histery
    		my $fileText_= &readFile(&getTCLogFname_($tcname)); # for _tcLogAppendix_.txt (pyAnvil logs)
    		if (-e $tcname) {;} else {mkpath $tcname;}
	 	open Fout, "> $tcname\\_tcLog.html" || die "Warning: $tcname\\_tcLog.html doesn't exist\n";
		print Fout "<html><body><pre>\n";
         	print Fout "==================== Update on $currentTime Start ===================== $tcname\n";
    		print Fout  $fileText_ if ($fileText_);
    		print Fout  $fileText;
		print Fout "==================== Update on $currentTime End   ===================== $tcname\n\n"; 
         	print Fout "</pre></body></html>\n";
         	close Fout;
	 } elsif (&getTCLogFname ($tcname) =~ /_tcLogAppend\.txt\s*$/) { 
	    my  $webLogText =  &readFile("$tcname\\_tcLog.html");
	        $webLogText =~ s/<html>\s*<body>\s*<pre>\s*//;
	        $webLogText =~ s/<\/pre>\s*<\/body>\s*<\/html>\s*//;
	        $webLogText =~ s/\n/_nl_/g;
       		$webLogText =~ s/\s*_nl_\s*/\n/g;

    		my $fileText = &readFile(&getTCLogFname($tcname)); # todo Histery

    		my $fileText_ = &readFile(&getTCLogFname_($tcname)); # for _tcLogAppendix_.txt (pyAnvil logs)

		######## add html tags to $fileText_ #######  todo
		if ($fileText_) { $fileText_ = &addURLs($fileText_); }
		if ($fileText ) { $fileText  = &addURLs($fileText ); }
		######## add html tags to $fileText_ ####### 

    		if (-e $tcname) {;} else {mkpath $tcname;}
		open Fout, "> $tcname\\_tcLog.html" || die "Warning: $tcname\\_tcLog.html doesn't exist\n";
		print Fout "<html><body><pre>\n";
         	print Fout "==================== Update on $currentTime Start ===================== $tcname\n";
    		print Fout  $fileText_ if ($fileText_);
    		print Fout  $fileText;
		print Fout "==================== Update on $currentTime End   ===================== $tcname\n\n"; 
		print Fout $webLogText;
         	print Fout "</pre></body></html>\n";
         	close Fout;
	 } else {
    		if (-e "$tcname/_tcLog.html") {;} else {mkpath $tcname;
		open Fout, "> $tcname\\_tcLog.html" || die "Warning: $tcname\\_tcLog.html doesn't exist\n";
		print Fout "<html><body><pre>\n";
         	print Fout "==================== Update on $currentTime Start ===================== $tcname\n";
    		print Fout "$tcname has no log\n";
		print Fout "==================== Update on $currentTime End   ===================== $tcname\n\n"; 
         	print Fout "</pre></body></html>\n";
         	close Fout;
		}
	 } 
	 rmtree &getTCLogFname ($tcname) ;
	 return " tcLog[Append].[txt|html] are refreshed";
}

sub addURLs {
	my $return="";	
	foreach my $each (split "\n", shift ) {

		$_ = $each;
		s/_/_underscore_/g; s/\s/_ws_/g; s/\./_dot_/g; s/\\/_backslash_/g; s/\//_slash_/g; s/:/_col_/g; s/-/_dash_/g; s/\(/_leftPara/g; s/\)/_rightPara/g;
		s/\W//g;
		s/\_ws_/ /g; s/_dot_/\./g; s/_backslash_/\\/g; s/_slash_/\//g; s/_col_/:/g; s/_dash_/-/g; s/_underscore_/_/g; s/_leftPara/\(/g; s/_rightPara/\)/g;
		if (($_ !~ /href=\"/) && (/(.+)($c\S+)\s(.?)/i)) { 
		$return = $return.$1."<a href=\"file:////$2\">$_</a>$3\n";
		} else { 
			$return = $return.$_."\n";
		}
	} 

$return ;
}



sub ps12txt {
	my $return="";	
	foreach my $each (split "\n", shift ) {

		$_ = $each;
		s/_/_underscore_/g; s/\s/_ws_/g; s/\./_dot_/g; s/\\/_backslash_/g; s/\//_slash_/g; s/:/_col_/g; s/-/_dash_/g; 
		s/\W//g;
		s/\_ws_/ /g; s/_dot_/\./g; s/_backslash_/\\/g; s/_slash_/\//g; s/_col_/:/g; s/_dash_/-/g; s/_underscore_/_/g;
		s/^\s*//g;
		$return = $return."\n".$_;
	} 
	$return ;
}

sub addUrl {
	my $return; my $str = shift;
	foreach my $each (split /\n/, $str) {
		if ($each =~ /^\s*(.+\.html)/)  { 
			my $line = $1;
			$line =~ s/^\s*//g;
			$line =~ s/\s*$//g;
			$line =~ s/\\/\//g;
			$line =~ s/HTML:\s*/file:\/\/\//i;
			$line =~ s//file:\/\/\//;
			$return = $return.  "<a href=\"$line\">$each</a>\n";
		} elsif ($each =~ /^\s*(.+\.xml)/)  { 
			my $line = $1;
			$line =~ s/^\s*//g;
			$line =~ s/\s*$//g;
			$line =~ s/\\/\//g;
			$line =~ s/XML:\s*/file:\/\/\//i;
			$line =~ s//file:\/\/\//;
			$return = $return.  "<a href=\"$line\">$each</a>\n";
		} else {
			$return = $return.$each."\n";
		}

	}
	return $return;
}



################################################################################
#	Subroutine Name : getTCLogFname
#		Function: get valid Log (new log) fname 
#	Input Parameters: c:\TC*\_thLog.txt
#	Output/Returns  : noLog or hasWWWLog
################################################################################
sub getTCLogFname	{    	# 	Determine if a log exists (TH:TC Report)
    my $tcName  = shift;
    my ( $dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks
	    );
	my $mtimeLogWeb; 

    if (-e $tcName.'/thProperty.txt' )
     {
	    (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks
	    ) = stat($tcName.'\\'.'thProperty.txt');
    }

    my $tcNameLog = $tcName."/_tcLogAppend.txt";
    if (-e $tcNameLog) {
	    my (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimeLog, $ctime, $blksize, $blocks
	    ) = stat($tcNameLog);
		if ($mtimePropertyFile - $mtimeLog>= 0 ) { return $tcNameLog; }
    }

    $tcNameLog = "$tcName/_tcLog.txt";
    if (-e $tcNameLog) {
	    my (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimeLog, $ctime, $blksize, $blocks
	    ) = stat($tcNameLog);
	    if ( $mtimePropertyFile - $mtimeLog>= 2 ) { return $tcNameLog; }
    }
    return "noLog"; 
}

sub getTCLogFname_	{    	# 	Determine if a log exists (TH:TC Report)
    my $tcName  = shift;
    my ( $dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks
	    );
	my $mtimeLogWeb; 

    if (-e $tcName.'\\thProperty.txt' )
     {
	    (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks
	    ) = stat($tcName.'\\'.'thProperty.txt');
    }

    my $tcNameLog = $tcName."\\_tcLogAppend_.txt";
    if (-e $tcNameLog) {
	    my (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimeLog, $ctime, $blksize, $blocks
	    ) = stat($tcNameLog);
		if ($mtimePropertyFile - $mtimeLog>= 0 ) { return $tcNameLog; }
    }

    $tcNameLog = "$tcName\\_tcLog_.txt";
    if (-e $tcNameLog) {
	    my (
		$dev,  $ino,   $mode,  $nlink, $uid,     $gid, $rdev,
		$size, $atime, $mtimeLog, $ctime, $blksize, $blocks
	    ) = stat($tcNameLog);
	    if ( $mtimePropertyFile - $mtimeLog>= 2 ) { return $tcNameLog; }
    }
    return "noLog"; 
}

sub reportTCSummary {
	$reportHtmlSummaryStr = '';  

	my $MaxTCExecTime = 10;  # todo Hard coded veriable
	open Fin, "$SvrDrive/$SvrProjName/$reportHtmlHistory" || die "Can't open _tcReportHistory.html";

	my $fname_ =	$SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlSummary."_"; 
	while (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlSummary."_") { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }

	open Fout, "> $SvrDrive/$SvrProjName/$reportHtmlSummary"."_" || die "Can't open _tcReportSummary_.html";

	$reportHtmlSummaryStr = "<html><body><pre>\n"; $reportHtmlSummaryStr = $reportHtmlSummaryStr . "<META http-equiv=\"refresh\" content=\"20\"> ";
	$reportHtmlSummaryStr = $reportHtmlSummaryStr .  "\n_replace_here_";
 	my $passFail ; my $dateTime; my $date1; my $date2; my %tcResult; my $tcName; my $passCtr=0;
	my $initStartTime = &UnixDate( "Jan 1, 2050", "%m/%d/%Y %H:%M:%S %Z" );
	my $endStartTime  = &UnixDate( "Jan 1, 1900", "%m/%d/%Y %H:%M:%S %Z" );
while ($_ =<Fin>) { 
	chop;
	if (($_ =~ /(testcase\d+)/) &&( $passCtr ==0 )) {
		$tcName = $1;	
		$reportHtmlSummaryStr = $reportHtmlSummaryStr . "\n$tcName: ";
		$_ = <Fin>;
		if ($_ =~ /^\s+(\w+)\s+\w+\s+(\d+\-\d+\-\d+\s+\d+:\d+:\d+)\s+/) {
		$_ =~ /^\s+(\w+)\s+\w+\s+(\d+\-\d+\-\d+\s+\d+:\d+:\d+)\s+/;
		$passFail = $1; $dateTime= $2; $date1=&ParseDate($dateTime); 
		if (&Date_Cmp( &ParseDate($initStartTime), &ParseDate($dateTime) ) >=0 ) { $initStartTime = $dateTime; }
		if (&Date_Cmp( &ParseDate($endStartTime),  &ParseDate($dateTime) ) <=0 ) { $endStartTime  = $dateTime; }
		if ($passFail =~ /pass/i) { $passFail = '<a style="color:green">*</a>';	} elsif ($passFail =~ /fail/i) { $passFail = '<a style="color:red">*</a>';} elsif ($passFail =~ /mark/i)  {$passFail ="|";}
		$reportHtmlSummaryStr = $reportHtmlSummaryStr . $passFail;
		}
	} elsif (/^\s+(\w+)\s+\w+\s+(\d+\-\d+\-\d+\s+\d+:\d+:\d+\s+)/) {
		$_ =~ /^\s+(\w+)\s+\w+\s+(\d+\-\d+\-\d+\s+\d+:\d+:\d+\s+)/;
		$passFail = $1; $dateTime= $2;
		if ($passFail =~ /pass/i) { $passFail = '<a style="color:green">*</a>';	} elsif ($passFail =~ /fail/i)  { $passFail = '<a style="color:red">*</a>';} elsif ($passFail =~ /mark/i) {$passFail ="|";} elsif ($passFail =~ /null/i) { $passFail = "_";}
		$date2=&ParseDate($dateTime); 
		if (&Date_Cmp( &ParseDate($initStartTime), &ParseDate($dateTime) ) >=0 ) { $initStartTime = $dateTime; }
		if (&Date_Cmp( &ParseDate($endStartTime),  &ParseDate($dateTime) ) <=0 ) { $endStartTime  = $dateTime; }

		my $delta=&DateCalc($date2,$date1); $delta =~ s/\+//g; my ($Y,$M,$W,$D,$H,$MIN,$S) = split /:/, $delta;
		my $totalMIN ;
		if ($Y && $M && $D && $H && $MIN && $S && $reportHtmlSummaryScale) {	
		$totalMIN = int ((((($Y*365 + $M * 30 + $D) * 24 + $H) * 60 + $MIN) * 60 + $S)/$reportHtmlSummaryScale) ;
		} else {
		$totalMIN = 0;
		}


		$reportHtmlSummaryStr = $reportHtmlSummaryStr . $passFail;
	}
}

 	my $totalTimeSpan = &DateCalc($initStartTime,$endStartTime);  my ($Y,$M,$W,$D,$H,$MIN,$S) = split /:/, $totalTimeSpan;
	my $NofX          = int ((((($Y*365 + $M * 30 + $D) * 24 + $H) * 60 + $MIN) * 60 + $S)/$reportHtmlSummaryScale) ;
	my $X_Unit = int (3600/$reportHtmlSummaryScale);	

	$reportHtmlSummaryStr = $reportHtmlSummaryStr. "\n_replace_here_\n";
	$reportHtmlSummaryStr = $reportHtmlSummaryStr .  "</pre></body></html>\n";

	my $tmp = "---------- |<marquee width = 50><--</marquee> ".&UnixDate($endStartTime, "%m/%d/%Y %H:%M:%S %Z")." ---------- $SvrDrive/$SvrProjName Test Summary -----...... <marquee width = 50><--</marquee>|". &UnixDate($initStartTime,  "%m/%d/%Y %H:%M:%S %Z" );
	$reportHtmlSummaryStr =~  s/_replace_here_/$tmp/g;
	print Fout $reportHtmlSummaryStr;
	close Fout;
	close Fin;
	move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlSummary."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlSummary);

}
################################################################################
#	Subroutine Name : reportTCHistory
#		Function: append TC result History to htmlLog
#	Input Parameters: Test Case name
################################################################################
sub reportTCHistory_ {
	my $tcname = shift;
	my $fileText = sprintf "%10s %s", "", &reportTC($tcname,"","History");
	&appendtoFile_ ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtmlHistory, " ---------------------- TestCase: <a name=\"".&getTCName($tcname)."\"> ".&getTCName($tcname)." </a>-----------------------\n");
	&appendtoFile_ ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtmlHistory, $fileText);
}


sub reportTCHistory {
	my $tcIdCtr_ = $tcIdCtr;
	my $tcname = shift;
	$tcIdCtr=1;
 	&createFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"");
 	&appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"<html><body><pre>\n");
find(sub { if ($File::Find::name =~ /tc\.pl$/i) {
			$SvrTCName = $File::Find::name; 
			$SvrTCName =~ s/\/tc.pl//g;
	my $fileText = sprintf "%10s %s", "", &reportTC($tcname,"","History");
	&appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory, " ---------------------- TestCase: <a name=\"".&getTCName($tcname)."\"> ".&getTCName($tcname)." </a>-----------------------\n");
	&appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory, $fileText);
	$tcIdCtr++;
		}
	 }, "$SvrDrive/$SvrProjName");
 	&appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"</pre></body></html>\n")				;
	$tcIdCtr = $tcIdCtr_;
}

################################################################################
#	Subroutine Name : reportTC
#		Function: report TC results on STDOUT and Update TCProj HTML
#	Input Parameters: TC Name
#			  TC PropertyName = tcRunResult
#			  TC Report Type: 0 = latest 1 = historyical
#	Output/Returns  : TC Reports displayed on webUI
################################################################################
sub reportTC() {		# TC Report Function (TH:TC Report)
	my $tcPropertyPatternPattern_ = ".*"; ####################### Reset the tcPropertyPatternPattern for index.htm
    my $cmd=''; $cmd = shift; if ($cmd !~ /^\s*cmd\s*=/i) { unshift @_, $cmd; } ;
    my $timeSpan  = "2000!now"; 
    my $tcname          = $_[0]; my $propertyPattern = $_[1]; my $reportType = $_[2]; 
    $tcname = &getTCName($tcname);
    my ($timeSpanStart, $timeSpanEnd, $isInSpan, $beautifiedStr, $beautifiedStr4Web); 
    my $returnValue="";
    my ($propertyName, $startTime, $endTime, $comment1, $comment2) ;
    my $passCtr =0; my $failCtr = 0; my $totalTime=0; my $avgResponseTime; my $propertyValue ='';
    my $totalTimeDummy; my $passFailDisplay="";
	&readTestSuitProperty();
    if( $propertyPattern =~ /^\s*$/) {   $propertyPattern = 'tcRunResult';}
    if( $reportType =~ /^\s*$/) {   $reportType = 'lastValue';}

    if ($timeSpan) { $_ = $timeSpan;
 	    ($timeSpanStart, $timeSpanEnd ) = split( /!|\|/, $timeSpan );
 	    $timeSpanStart = &ParseDate($timeSpanStart);
 	    $timeSpanEnd   = &ParseDate($timeSpanEnd);
    }
     my $tcPassFailDisplayWidth = 0; 
#    ############ get maxPassFailDisplayWidth #################
     open Fin, "$tcname/thProperty.txt" || die "Can't open file:$!"; 	################## Read Property File
#    ############################## Read Property File to update reportHtmlHistory ###########################
     while ( $_ = <Fin> ) { chop;
          if ( $_ =~ /$propertyPattern/i ) {
                 ( $propertyName, $propertyValue, $startTime, $endTime, $totalTimeDummy, $comment1, $comment2) = split( '\|', $_);
                 my $flag1 = &Date_Cmp( &ParseDate($startTime), &ParseDate($timeSpanStart) );
                 my $flag2 = &Date_Cmp( &ParseDate($timeSpanEnd), &ParseDate($endTime) );
                  if   ( ( $flag1 >= 0 ) && ( $flag2 >= 0 ) ) { $isInSpan = 1; }
                  else                                        { $isInSpan = -1; }
 		my $date1=&ParseDate($startTime); my $date2=&ParseDate($endTime); my $delta=&DateCalc($date1,$date2); $delta =~ s/\+//g;
 		my ($Y,$M,$W,$D,$H,$MIN,$S) = split /:/, $delta;
 		my $totalSec = $D * 24 * 3600 + $H * 3600 + $MIN * 60 + $S;
 		if ($propertyValue =~ /^\s*[\d|.]+\s*$/) { $totalSec = $propertyValue; $propertyValue = "Perf";}
              if ( $isInSpan == 1 ) {;
 		 if ( $propertyPattern =~ /tcRunResult/i ) {
     			$tcPassFailDisplayWidth= $tcPassFailDisplayWidth + 1 ;
                       }
   	     } # endif for InSpan
          }    # endif for /propertyPattern/
     }		
     close Fin;

# todo no-intellegence now 	if (($passFailDisplayWidth < $tcPassFailDisplayWidth) and ($tcPassFailDisplayWidth < $maxPassFailDisplayWidth)) { $passFailDisplayWidth = $tcPassFailDisplayWidth; }
# todo	else { $passFailDisplayWidth = $maxPassFailDisplayWidth;}

 
    ############ get maxPassFailDisplayWidth #################
    open Fin, "$tcname/thProperty.txt" || die "Can't open file:$!"; 	################## Read Property File
    ############################## Read Property File to update reportHtmlHistory ###########################
    while ( $_ = <Fin> ) { chop;
         if ( $_ =~ /$propertyPattern/i ) {
                ( $propertyName, $propertyValue, $startTime, $endTime, $totalTimeDummy, $comment1, $comment2) = split( '\|', $_);
                my $flag1 = &Date_Cmp( &ParseDate($startTime), &ParseDate($timeSpanStart) );
                my $flag2 = &Date_Cmp( &ParseDate($timeSpanEnd), &ParseDate($endTime) );
                if   ( ( $flag1 >= 0 ) && ( $flag2 >= 0 ) ) { $isInSpan = 1; }
                else                                        { $isInSpan = -1; }
		my $date1=&ParseDate($startTime); my $date2=&ParseDate($endTime); my $delta=&DateCalc($date1,$date2); $delta =~ s/\+//g;
		my ($Y,$M,$W,$D,$H,$MIN,$S) = split /:/, $delta;
		my $totalSec = $D * 24 * 3600 + $H * 3600 + $MIN * 60 + $S;
		if ($propertyValue =~ /^\s*[\d|.]+\s*$/) { $totalSec = $propertyValue; $propertyValue = "Perf";}
             if ( $isInSpan == 1 ) {
		 if ( $propertyPattern =~ /tcRunResult/i ) {
		      $beautifiedStr = sprintf "%15s %-15s %-25s%-s", $propertyValue, $totalSec.'s', $startTime, $comment1;
		      if ($propertyValue =~ /pass/i) {$passCtr++; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."p";}
		      if ($propertyValue =~ /fail/i) {$failCtr++; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."f";}
		      if ($propertyValue =~ /mark/i) {          ; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."m";}
		 } else {
                 	$beautifiedStr = $_;
             	 }    # endif for /tcRunResult/
                 if ( $reportType =~ /history/i ) {    		# return property history
			 # $returnValue .= "$beautifiedStr\n";
                     $returnValue = "$beautifiedStr\n$returnValue";
                 }
                 elsif ( $reportType =~ /lastValue/i ) {    	# returen last property
                     $returnValue = $beautifiedStr;
                 }
                 elsif ( $reportType =~ /forWeb/i ) {    	# for the web
                         $returnValue .= $beautifiedStr4Web;
                     }
	     } # endif for InSpan
         }    # endif for /propertyPattern/
    }									##################### 
    ############################## Read Property File to update reportHtmlHistory ###########################

    	if ($passCtr + $failCtr == 0) {				##########  Generate TC webUI string 
	$avgResponseTime = 0; } else {
	$avgResponseTime = $totalTime / ($passCtr + $failCtr); 
	}
	my $qtpHost; my $ATResultFname; my %color; my $color = 'gray'; my @color; my $colorIndex = 0; my $QASvrName; my $expFailure="";
	if ($propertyValue =~ /pass/i) { $color = "Green"; } elsif ($propertyValue =~ /fail/i) { $color = 'Red'; }
	elsif ($propertyValue =~ /expected\s*fail/i) { $expFailure = "_Expected_Failure_ "; }

	$color[0]=1;

	##### testcase Desc #### 
	my $TCDesc_displayTip = "Click to view TC logs";
	my $TCDesc_display ; my $TCDesc_display_ ;
	if ($tsProperty{$tcname}) { #$TCDesc_display = sprintf "%-80s", $tsProperty{$tcname}; 
		###### Handle expected failure 
		if (($tsProperty{$tcname} =~ /_expected_fail_/i) && ($propertyValue =~ /fail/i)){ $color = "Green"; }
		if (($tsProperty{$tcname} =~ /_expected_fail_/i) && ($propertyValue =~ /pass/i)){ $color = "Red"; }
		###### Handle expected failure 
		$TCDesc_display_ = $expFailure.$tsProperty{$tcname};

		if (length($TCDesc_display_) <= $webUI_TCDescWidth ) { # todo hardcoded 
		$TCDesc_display = sprintf "%-80s", $TCDesc_display_; 
		} else {
		$TCDesc_display = sprintf "%-80s", substr $TCDesc_display_, 0, $webUI_TCDescWidth; 
		$TCDesc_displayTip = $tsProperty{$tcname}; 
		}

	} else { $TCDesc_display = sprintf "%-80s", $tcname; }

	# prHtml3 mark for search

	my $tcSerialN = $TCDesc_display; if ($tcSerialN =~ /^\s*\d+\s+/) {$tcSerialN =~ /^\s*(\d+)\s+/; $tcSerialN = "$1"; if ($tcSerialN) {;} else {$tcSerialN = "";}}
	my $dirRoot = &getRoot($tcname); 
	my $TCCtrToolTip = sprintf "Run Test (Testcase Number == $tcSerialN [%s])", &timeConvert($avgResponseTime); 
	my $TCCtrToolTipMin = sprintf "Run Tests (Testcase Number >= $tcSerialN)" ; 
	my $TCScrollAmount = 0; my $CtrSeparator = "|";
	my $perl = $^X;  $perl =~ s/\\/\\\\/g;
	my $tmp11= sprintf("<a href=\"${url}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName exitTAF')\" title=\"Stop Test\" >");
	$passFailDisplay = &genPassFailDisplay($passFailDisplay);

	my $tmp = sprintf( "<span style=\"color:black;\">$passFailDisplay${tmp11}.</a> <font color=\"$color[$colorIndex]\"> <a href=\"${url}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName -s drive=$SvrDrive;tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;testcaseExec=$dirRoot;ExecutionType=runTC;exec')\"  title=\"$TCCtrToolTip\">%s</a>  <a href=\"${url}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName -s drive=$SvrDrive;tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;tcIdMin=$tcIdCtr;testsuit=$SvrProjName;ExecutionType=runTS;exec')\"  title=\"$TCCtrToolTipMin\"><marquee style=\"border:RED ${borderWidth}px ${borderStyle}\" width=48 direction=right behavior=alternate loop=10000 scrollamount=$scrollAmount>%s</marquee></a></font><a href=\"${url}/$SvrProjName/".&getTCNameStr($SvrTCName)."/_tcLog.html\" title=\"$TCDesc_displayTip\">%-${webUI_TCDescWidth}s</a> <a href=\"${url}/$SvrProjName/${reportHtmlHistory}#$tcname\" title=\"Click to see Pass/Fail history\">%5d/%-5d</a> %6d(s)       <font color=\"white\"> %s </font></span>\n",
                    '>', 
		    '>|', 
		    $TCDesc_display,
                    $passCtr,
                    $failCtr,
                    $avgResponseTime,
		    $tcname.'/tc.pl',
                );

	# http
	# todo: http miss the runPropertyPattern and tcIdMin function, ExecutionType 
	my $tmp_http = sprintf( "<li style=\"color:$color;\"><span style=\"color:black;\"><a href=\"${urlHttp}/$SvrProjName/".&getTCNameStr($SvrTCName)."/_tcLog.html\" title=\"$TCDesc_displayTip\"> %-80s</a> <a href=\"${urlHttp}/$SvrProjName/${reportHtmlHistory}#$tcname\" title=\"Click to see Pass/Fail history\">Pass/Fail</a>:<font color=\"$color[$colorIndex]\"> <a href=\"${urlHttp}/$SvrProjName/$reportHtml_http\" onClick=\"RunFile(\'http://$ip/$_TAF/$SvrProjName/$dirRoot/tc.hta\')\"  title=\"$TCCtrToolTip\">%5d$CtrSeparator<marquee style=\"border:RED ${borderWidth}px ${borderStyle}\" width=48 direction=right behavior=alternate loop=10000 scrollamount=$scrollAmount>%-5d</marquee></a></font>  %6d(s) <font color=\"white\"> %s </font></span></li>\n",
		    $TCDesc_display,
                    $passCtr,
                    $failCtr,
                    $avgResponseTime,
		    $tcname.'/tc.pl',
                );


		if ($cmd =~ /noprint/i) {;} else { 
			&appendtoFileUniq_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1, $tmp 		);
			&updateWeb1_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml, $tmp			);  

			 	&appendtoFileUniq_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1_http, $tmp_http 	); 
			&updateWeb1Http_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml_http, $tmp_http		); 
		 } 
     	close Fin;
     	if ($returnValue) {$returnValue =~ s/^\s*//g;} else {$returnValue = "";} 
     	return $returnValue;
}

sub genPassFailDisplay {
	my $str = shift;
	$str = reverse $str;	
	$str = $str. "                                                        ";	 
	$str = substr ($str, 0, $passFailDisplayWidth);
	$str =~ s/p/<a style=\"color:green\">*<\/a>/g;
	$str =~ s/f/<a style=\"color:red\">*<\/a>/g;
	$str =~ s/m/|/g;
	if ($str =~ /^\s*$/) { $str = &genStr($passFailDisplayWidth);}
	return $str; 
}

sub genStr { my $strLen = shift; my $return=""; for (my $i = 0; $i < $strLen; $i++) { $return  .= " "; } $return; }

sub processTSs{
	shift;
	my $tmp = shift;
	@_ = split /;/, $tmp;
	foreach my $each (@_) {
		if ($each !~ /=/) {
			if ($each =~ /\bmarkblablaaaaa\b/i) { 							;
			} else  {
				; 
 				#print "pd: $SvrProjName,  $each\n"; my $str =  "\&$each();"; my $rst = eval $str; next				;  
			}
		} else {
			$each =~ /^\s*(\S+)\s*=\s*(\S+)\s*/; my $varName = $1; my $varValue = $2		;
			if (($varName !~ /^\s*$/) && ($varValue !~ /^\s*$/)) {
				if ($varName =~ /\bcreate\b/i) { &createTS($varValue); }
				elsif ($varName =~ /\badd\b/i) 	{ &addTS($varValue); }
				elsif ($varName =~ /\bdelete\b/i) { &deleteTS($varValue); }
				else {
					print "Unrecognized Testsuite Command: $varName\n"; 		
				}
			}
		}
	} 
}


sub processTCs{
	shift;
	my $isBatchProcessing = 1;
	my $tmp = shift;
	@_ = split /;/, $tmp;
	&genDriver_taf_pl ();
	foreach my $each (@_) {
		if ($each !~ /=/) {
			$isBatchProcessing = 0;
			if (($each =~ /\blistVars\b/i) || ($each =~ /\bgetVars\b/i)) { return &getGlobalVars()	;
			} elsif ($each =~ /\bprintVars\b/i) { print &getGlobalVars(); next 			;
			} elsif ($each =~ /\bexec\b/i) { 							;
				&setGlobalVars("","tcOP=exec")							;
				$isBatchProcessing = 1								;
			} elsif ($each =~ /\blistTcFilters|printTcFilters\b/i) { 							;
				&setGlobalVars("","tcOP=listtcfilters")							;
				$isBatchProcessing = 1								;
			} elsif ($each =~ /\blist\b/i) { 							;
				&setGlobalVars("","tcOP=list")							;
				$isBatchProcessing = 1								;
			} elsif ($each =~ /\bmark\b/i) { 							;
				&setGlobalVars("","tcOP=mark")							;
				$isBatchProcessing = 1								;
			} elsif ($each =~ /\blistAll\b/i) { 							;
			 	$SvrTCNamePattern =".*";  &listAll()						; 
				$isBatchProcessing = 0								;		
			} elsif ($each =~ /customer1/i) {
				&customer1();
			} else  {
				my $str =  "\&$each();"; my $rst = eval $str; 
				if ($rst) { print "\`$each\` = \"$rst\"\n"; } else { print "\`$each\` is not a TAF command."; }
				next;  
			}
		} else {
			if ( $each =~ /^\s*(\S+)\s*=\s*(\S+)\s*/ ) {
			$each =~ /^\s*(\S+)\s*=\s*(\S+)\s*/; my $varName = $1; my $varValue = $2		;
			if (($varName !~ /^\s*$/) && ($varValue !~ /^\s*$/)) {
				$isBatchProcessing = 1;
				if (&setGlobalVars ("","$varName=$varValue;") == 1 ) 		{ ; }
				else {
					$isBatchProcessing = 0; my $rst = &processTC("",$each) 			;
				}
			}
			}
		}
	} 
	if ($isBatchProcessing == 1) {&tcLoop();}
}

################################################################################
#	Subroutine Name : process Test Case
#		Function: wrapper for Test Case management functions
#	Input Parameters: PropertyOP
#	Output/Returns  : tcName and propertyO/proc
################################################################################
sub processTC {
	    my $tcname; my $cmd="";
	    shift; my $tcOP= ''; $tcOP = shift if (@_); 
	    my $prMsg = '' ; $prMsg= shift if @_;
	    $tcOP =~ /\s*([\w|\d]+)\s*(=)?\s*(\w+)?\s*([;|\/])?(\s*\S+\s*)?/;  
	    $tcOP = $1; $tcname = $3; $cmd = $5; $prMsg = $pr2Screen;

	    # if ($cmd =~ /^\s*\.pl\b/) { $cmd = undef ;} 	# todo temporal fix 
	    ######## This is for TCs processing (Batching)
		if ($tcOP =~ /\blistAll\b/i) {
			# SvrTCName as a regExp
			if ($tcname =~ /^\s*$/) { $SvrTCNamePattern =".*";} else { $SvrTCNamePattern = $tcname; } 
			&listAll(); 
			return; 
			}
	    ######## The following are for TC processing 	    
 	    if ((defined $tcname) && ($tcname =~ /^.$/) && ($cmd =~ /:[\\|\/]/)) {
 			$tcname = $tcname.$cmd; # handle -s delete=c:\_ts1_
 	    }
	    $tcname =  &getTCName($tcname); 
	    printf "%-20s %-40s ", "processTC: ", $tcname   if $prMsg; # print for webUI 1/2
	    my $rst; 

	    if ( $tcOP =~ /^\s*create/i ) {
		    if ($cmd) { $rst = &createTC("cmd=$cmd",$tcname); }
		    else { $rst = &createTC($tcname); }
            } elsif ( $tcOP =~ /^\s*exec\b/i ) {
		    $rst = &execTC_($tcname);
            } elsif ( $tcOP =~ /^\s*mark\b/i ) {
		    $rst = &markTC_($tcname);
            } elsif ( $tcOP =~ /^\s*execAll/i ) {
		    $rst = &tcLoop();
		        return $rst;
            } elsif ( $tcOP =~ /^\s*UpdateWeb/i ) {
		    if (defined $cmd) {;} else { $cmd = 0;}
		    $rst = &updateWeb_($tcname,$cmd);
	    } elsif ( $tcOP =~ /^\s*getWeb_/i ) {
		    $rst = &getWeb_($tcname);
            } elsif ( $tcOP =~ /^\s*log/i ) {
		    $rst = &logTC($tcname);
            } elsif ( $tcOP =~ /^\s*detect/i ) {
		    $rst = &detectTC($tcname, $SvrProjName, $SvrDrive); 
            } elsif ( $tcOP =~ /^\s*getLogName/i ) {
		    $rst = &getTCLogFname(&getTCName($tcname)); 
	    } elsif ( $tcOP =~ /^\s*listTCFilters/i ) {
		    $rst = &getProperties(&getTCName($tcname) , '.*_all_', 'latest');
	    } elsif ( $tcOP =~ /^\s*printtcFilters/i ) {
		    $rst = &getProperties(&getTCName($tcname) , '.*_all_', 'latest');
            } elsif ( $tcOP =~ /^\s*printResult/i ) {

	    } elsif ( $tcOP =~ /^\s*list|get\b/i ) {
		    $rst = &getProperties(&getTCName($tcname) , 'tcRunResult', 'latest');
		    # todo !!! Might break other functions !!!
		    # if (defined $cmd) { $rst =  &reportTCHistory($tcname); } else { $rst = &reportTC($tcname,"","lastValue") ; }

            } elsif ( $tcOP =~ /^\s*delete/i ) {
		    $tcOP =~ s/^\s*delete\s*=//g;
		    $tcOP =~ s/\s*$//g;
		    $rst = &deleteTC($tcname);
            } else {
		    print "<- Test suite \n" if $prMsg;
		return "_noProcessedTC_";
	    }
	     	printf "%s\n",  $rst  if $prMsg; # print for webUI 2/2
	 	$rst = sprintf "%-20s %-40s %s", "processTC:", $tcname,  $rst ;
		return $rst;
}


sub listAll { 
	find(\&recursiveSearchListAll, $SvrDrive); }
sub recursiveSearchListAll() { 
	if (($File::Find::name =~ /tc.pl/) && ($File::Find::name =~ /$SvrTCNamePattern/i))
	{	
		print "$File::Find::name\n"; 
	
	}
}

sub createTS {
	my $tsName = "_testsuite_"; $tsName = shift if @_;
	my $rst = mkpath $tsName;
	print " --> Create Testsuite: $tsName  ($rst) \n";
	$workingDir = $tsName;
	&generatePerl_pl_template();
	return $rst;
}
sub addTS {
	my $tsName = "_testsuite_"; $tsName = shift if @_;
	if (-e $tsName) { print " --> Add Testsuite Hook : $tsName \n"; return 0; } 
	else { print "[Warning] Testsuite ($tsName) doesn't exist. No testsuite hook is added\n";
		return 1;}
}

sub deleteTS {
	my $tsName = "_testsuite_"; $tsName = shift if @_;
	my $rst = rmtree $tsName;
	print " --> Delete Testsuite: $tsName ($rst) \n";
	return $rst;
}
sub createTC {
	my $tc_pl="tc.pl";
	my $cmd=''; $cmd = shift; if ($cmd !~ /^\s*cmd\s*=/i) { unshift @_, $cmd; } ;
	my $tcNameRoot = "@_"; my $sleep = 0;
	if ($cmd =~ /sleep\s*=\s*(\d+)/ ) { $sleep = $1; }
	my $tcName = &getTCName(@_);
	if( &detectTC($tcName) =~ /exists/ && ($cmd !~ /Over/i)) { # overwrite
		return "Warning $tcName already exist! (-create;cmd=overwrite)" ; } 
	else {
		mkpath($tcName);
		######################## tc.hta ##########################

	@_ = split "\/", $tcName;
	my $testsuite = $_[2]; my $testcase  = $_[3]; 
	my $now = &UnixDate(&DateCalc("now","+ 6 seconds") , "%H:%M:%S" );

	if ($testsuite) {;} else { print "[Info] \$testsuite is null. Note \$tcName = $tcName\n"; $testsuite ="";}
	if ($testcase ) {;} else { print "[Info] \$testcase  is null. Note \$tcName = $tcName\n"; $testcase = "";}

	my $tcNameIIS = $tcName; 
	if ($tcNameIIS) {;} else { print "[Info] \$tcName is null, \$tcNameIIS = $c.':/inetpub/wwwroot/'\n"; $tcNameIIS = $c.':/inetpub/wwwroot/';}
	# &createFile( $tcNameIIS.'\\'.'tc.hta', 
	&createFile( $tcNameIIS.'/'.'tc.hta', 
"
<html>
<head>
	<script language=\"JavaScript\">
		function RunFileHTTP(testsuite, testcase) {
//			alert(\"testsuite is \" + testsuite + \" testcase is \" + testcase );
			 WshShell = new ActiveXObject(\"WScript.Shell\");
		    	 cmd= '$c\\\\windows\\\\system32\\\\schtasks.exe /delete /tn TAF_'+ testsuite + '_' + testcase + ' /f'; 
			sleep (1000);
 //alert (cmd);
			 WshShell.Run(cmd, 1, false);
			 cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /create /TR \"$c\\\\$_TAF\\\\taf.pl testsuit='+testsuite+';testcaseExec='+testcase+';exec\" /TN TAF_'+testsuite+'_'+testcase+' /sc monthly /mo 1 /F'; 
			sleep (1000);
 //alert (cmd);
			 WshShell.Run(cmd, 1, false);
    		  	 cmd= '$c\\\\windows\\\\system32\\\\schtasks.exe /run /tn TAF_'+testsuite+'_'+testcase; 
			sleep (1000);
 //alert (cmd);
			 WshShell.Run(cmd, 1, false);
		}

	function sleep(milliseconds) {
	  var start = new Date().getTime();
	  for (var i = 0; i < 1e7; i++) {
	    if ((new Date().getTime() - start) > milliseconds){
	      break;
	    }
  	}
}


// <a onclick=\"RunFileHTTP(\'$testsuite\', \'$testcase\')\">Click this to run Run Program</button> <p>
	</script>
</head>
<body onLoad =\"RunFileHTTP(\'$testsuite\', \'$testcase\')\">Run $testsuite\/$testcase\/tc.hta</button> <p>
</body>
</html>
"
 			);

		######################## tc.hta ##########################
		if ($cmd =~ /Perf/i) {  # PerformanceTC
		&createFile( $tcName.'\\'.$tc_pl, "\$| = 1; print \"1234567.89\\n\"; sleep $sleep; ");
		} elsif ($cmd =~ /ExpectedFail/i) { # ExpectedFailedTC
		&createFile( $tcName.'\\'.$tc_pl, "\$| = 1; print \"Expected_f_a_i_l\\n\"; sleep $sleep; ");
		} elsif ($cmd =~ /Fail/i) { # FailedTC
		&createFile( $tcName.'\\'.$tc_pl, "\$| = 1; print \"fail\\n\"; sleep $sleep; ");
		} elsif ($cmd =~ /customTC/i) { # CustomTC
			$cmd=~ /customTC:\s*(.+)\s*:customTC/; $cmd =$1; $cmd =~ s/_space_/ /;

			if ($cmd =~ /ps1\s*/) {	# Powershell plugin
			###########
			&createFile( $tcName.'\\'.$tc_pl, 
"
use File::Copy;\n\$| = 1;
if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\"  ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"".&getDir($cmd)."\/_tcLogAppend.bak\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"".&getDir($cmd)."\/_tcLogAppend_.bak\");}
print `powershell -executionpolicy unrestricted -file $cmd $ps1_args`;  # custom TC tc.pl 
if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\"  ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"$tcName\/_tcLogAppend.txt\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"$tcName\/_tcLogAppend_.txt\");}
"
			);
			###########
			} elsif (($cmd =~ /pyanvil/i) &&( $tc_pl =~ /index_pyAnvil\.pl/i)) { 		# pyAnvil plugin
			###########
			&createFile( $tcName.'\\'.$tc_pl, 
"
use File::Copy;\n\$| = 1;
if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\"  ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"".&getDir($cmd)."\/_tcLogAppend.bak\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"".&getDir($cmd)."\/_tcLogAppend_.bak\");}
print `$cmd $ps1_args`; 	# tc.pl
if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\"  ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"$tcName\/_tcLogAppend.txt\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"$tcName\/_tcLogAppend_.txt\");}
"
			);
			###########
			} elsif  ($cmd =~ /\S+\.pl\s*/) { 		# perl plugin 
			###########
			&createFile( $tcName.'\\'.$tc_pl, 
"
use File::Copy;\n\$| = 1;
if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\"  ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"".&getDir($cmd)."\/_tcLogAppend.bak\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"".&getDir($cmd)."\/_tcLogAppend_.bak\");}
print `$cmd`;  # c:\\$_TAF\\index.pl
if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\"  ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"$tcName\/_tcLogAppend.txt\");}
if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"$tcName\/_tcLogAppend_.txt\");}
"
			);
			###########
			} elsif ( $cmd =~ /taftestcase1/) {
			###########
			&createFile( $tcName.'\\'.$tc_pl, 
"
\$| = 1; 
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue1_doit_`;
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=get_property1`;
if ( \$rst =~ /propertyValue1/) { print \"pass\\n\";} else {print \"fail\\n\";}
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue0_doit_`;
"
			);
			###########
				;
			} elsif ( $cmd =~ /taftestcase2/) {
			###########
			&createFile( $tcName.'\\'.$tc_pl, 
"
\$| = 1; 
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue1A_doit_`;
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=get_property1`;
if ( \$rst =~ /propertyValue1A/) { print \"pass\\n\";} else {print \"fail\\n\";}
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue0_doit_`;
"
			);
			###########
				;
			} elsif ( $cmd =~ /taftestcase3/) {
			###########
			&createFile( $tcName.'\\'.$tc_pl, 
"
\$| = 1; 
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property2_as_propertyValue2_doit_`;
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=get_property2`;
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;propertyOP=get_property2`;
if (( \$rst =~ /testcase1/) && (\$rst =~ /testcase2/) && (\$rst =~ /property2\\s*=\\s*propertyValue2/)) { print \"pass\\n\";} else {print \"fail\\n\";}
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue0_doit_`;
"
			);
			###########
				;
			} elsif ( $cmd =~ /taftestcase4/) {
			###########
			&createFile( $tcName.'\\'.$tc_pl, 
"
\$| = 1; 

\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property2_as_propertyValue1_doit_`;
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property2_as_propertyValue2_doit_`;
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property2_as_propertyValue2A_doit_`;
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property1_as_propertyValue1A_doit_`;
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;printTcFilters`;
if (( \$rst =~ /property1\\s+propertyValue1A/) && (\$rst =~ /property2\\s+propertyValue2A/))  { print \"pass\\n\";} else {print \"fail\\n\";}

\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue0_doit_`;
\$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property2_as_propertyValue0_doit_`;
"
			);
			###########
				;
			} else {
				;
			}
		} else {
			 &createFile( $tcName.'\\'.$tc_pl, "\$| = 1; print \"pass\\n\"; sleep $sleep; ");
		}
        	&createPropertyTemplate($tcName);

		my $tmp =<<EOF;
open Fout, '>$tcName\\_tcLogAppend.txt';
print Fout "* This is the content of TC log file\\n";
print Fout "* TC Log can has URL pointed to <a href=\\"file:////$c/$_TAF/blabla.html\\" >File Archieve</a>\\n";
print Fout "* TC Log can has URL pointed to <a href=\\"file:////$c/$_TAF/_testsuite2_/_testcase1_/_tcLog.html\\" >Another TC's Log</a>\\n ";
print Fout "* TC Log can has URL pointed to <a href=\\"file:////$c/$_TAF/index.htm\\" >TAF</a>\\n";
close Fout;
exit;
EOF
		if (($cmd =~ /genLog/i) || ($cmd =~ /addLog/i)) {&appendtoFile( $tcName.'\\'.$tc_pl, $tmp) ; undef $tmp; }
	$tcName =~ s/\\\\/\\/g;

	return "is created";
	}
}

sub execTC {
	my $tcName = &getTCName(@_); my $timeStart = &getDate(); my $rst=''			; 
	if  ( -e "$tcName/tc.pl" ) {
		my $cmd     = "$tcName/tc.pl"; $rst     = `$cmd`; my $timeEnd= &getDate()	; 
	       $rst =~ /(pass|fail|todo|[\d|.]+)$/i; $rst = $1; 
	       if ($rst) {;} else {$rst = "null";} # todo Hardcoded 
	       if (($rst =~ /Expected_f_a_i_l/i) || ($rst =~ /null/i)) { sleep 10; }
	       $rst =~ s/^\s*0+//g;
	       my $rstStr = sprintf "%20s|%10s|%s", "tcRunResult",$rst , $timeStart		;
	       $rstStr .= "|"; $rstStr .= "$timeEnd"; $rstStr .= "|"; $rstStr .= "0:0:0:0s"; $rstStr .= "|"; 
	       if ( $rst =~ /^\s*[\d+|\.]+\s*$/ ) { $rstStr .= "Performance Test ($rst) "; } 
	       else { $rstStr .= "Functional Test ($rst) "; } 
	       $rstStr .= '|comment2'; 
	       &addProperty(&getTCName($tcName), "add=$rstStr");
	       return $rst;
       } else {
	       return "tcName: $tcName doesn't exist.\n";
       }
}

sub markTC_ {
	my $tcName = &getTCName(@_);
	my $timeStart = &getDate(); my $rst=''; 
	if  ( -e "$tcName/$tc_pl" ) { 
		my $cmd     = "$tcName/$tc_pl"; $rst = "mark"; # $rst     = `$cmd`; 
		my $timeEnd= &getDate(); 
	       $rst =~ /(mark|pass|fail|todo|[\d|.]+)$/i; $rst = $1; 
	       if ($rst) {;} else {$rst = "null";}
	       $rst =~ s/^\s*0+//g;
	       my $rstStr = sprintf "%20s|%10s|%s", "tcRunResult",$rst , $timeStart;
	       $rstStr .= "|"; $rstStr .= "$timeEnd"; $rstStr .= "|"; $rstStr .= "0:0:0:0s";
	       $rstStr .= "|"; 
	       if ( $rst =~ /^\s*[\d+|\.]+\s*$/ ) {
		$rstStr .= "Performance Test ($rst) ";
	       } else {
	       $rstStr .= "Functional Test ($rst) ";
	       } 
	       $rstStr .= '|comment2'; 
	       &addProperty(&getTCName($tcName), "add=$rstStr");
	       return $rst;
       }
       else {
		return "tcName: $tcName doesn't exist.\n";
       }

}


sub execTC_ {
	my $tcName = &getTCName(@_);
	my $timeStart = &getDate(); my $rst=''; 
	if  ( -e "$tcName/$tc_pl" ) { 
		my $cmd     = "$tcName/$tc_pl"; $rst     = `$cmd`; 
		my $timeEnd= &getDate(); 
	       $rst =~ /(pass|fail|todo|[\d|.]+)$/i; $rst = $1; 
	       if ($rst) {;} else {$rst = "null";}
	       $rst =~ s/^\s*0+//g;
	       my $rstStr = sprintf "%20s|%10s|%s", "tcRunResult",$rst , $timeStart;
	       $rstStr .= "|"; $rstStr .= "$timeEnd"; $rstStr .= "|"; $rstStr .= "0:0:0:0s";
	       $rstStr .= "|"; 
	       if ( $rst =~ /^\s*[\d+|\.]+\s*$/ ) {
		$rstStr .= "Performance Test ($rst) ";
	       } else {
	       $rstStr .= "Functional Test ($rst) ";
	       } 
	       $rstStr .= '|comment2'; 
	       &addProperty(&getTCName($tcName), "add=$rstStr");
	       return $rst;
       }
       else {
		return "tcName: $tcName doesn't exist.\n";
       }

}


sub deleteTC {
	if ($_[1]) { $SvrProjName = $_[1];}
	if ($_[2]) { $SvrDrive = $_[2];}
	my $tcName = &getTCName(@_);
#### 	todo	backup deleted TCs. move ($tcName, $tcName."_".  &UnixDate( "now", "%m_%d_%Y_%H_%M_%S_%Z" ) ."_backup");
	rmtree $tcName;
	return "$tcName is deleted (saved as *_backup)";
}

sub detectTC {
	if ($_[1]) { $SvrProjName = $_[1];}
	if ($_[2]) { $SvrDrive = $_[2];}
	my $tcName = '';
	$tcName = &getTCName(@_);
     	if (-e "$tcName\\tc.pl" ) { return  "exists"; } else { return 'does not exist';}
}

sub getTCName {
	my $SvrProjNameTmp; my $SvrDriveTmp; my $SvrTCNameTmp ;  
	$SvrTCNameTmp = shift if @_; 
	if ($notUsegetTCName==1) { return $SvrTCName;}
	if ($SvrTCNameTmp) {;} else { $SvrTCNameTmp = $SvrTCName; }  
	if ($SvrProjNameTmp) {;} else {  $SvrProjNameTmp = $SvrProjName;}  
	if ($SvrDriveTmp) {;} else {  $SvrDriveTmp = $SvrDrive;}  
	if ($SvrTCNameTmp =~ /[a-z]:/i) {
		return  $SvrTCNameTmp;
	} else {
		return ($SvrDriveTmp.'/'.$SvrProjNameTmp.'/'.$SvrTCNameTmp) ;
	}
}

sub getTCNameStr{
	my $SvrTCNameStr = shift;
	@_ = split /\\|\//, $SvrTCNameStr; 
	pop;
}

################################################################################
#	Subroutine Name : processProperty
#		Function: wrapper for property management functions
#	Input Parameters: PropertyOP
#	Output/Returns  : tcName and propertyOp
################################################################################
sub processProperty {
	shift; my $tcname = shift; my $propertyOP = shift; my $rst=""; my $prMsg=0;
	#### PropertyOp String Translation
		$propertyOP =~ s/^\s*propertyOp\s*=//g; $propertyOP =~ s/^\s*po\s*=//g; $propertyOP =~ s/_doit_//g;
	if ($propertyOP =~ /^\s*_?set_(.+)_(as|eq)_(.+)/) { $propertyOP = "add_eq_$1_column_$3"; }
	if ($propertyOP =~ /^\s*_?get_(.+)/) { $propertyOP = "get_$1"; }
	#### PropertyOp String Translation

	if (defined $propertyOP) {;} else { $rst = "Warning: wrong format. Correct format is -add=prop:value"; 
		return $rst; }
	if ($propertyOP =~ /;\s*pr2Screen\s*/) { $prMsg = 1; $propertyOP =~ s/;\s*pr2Screen\s*(=\s*\d*\s*)?//; }
	if ( $propertyOP =~ /^\s*add/i ) {
                $rst = &addProperty( &getTCName($tcname), $propertyOP );
        }
        elsif ( $propertyOP =~ /^\s*del/i ) {
                $rst = &deleteProperty( &getTCName($tcname), $propertyOP );
        }
        elsif ( $propertyOP =~ /^\s*reset/i ) {
                ;
        }    # copy to a backup and create a property file
        elsif ( $propertyOP =~ /^\s*modify/i ) {
                $rst = &modifyProperty( &getTCName($tcname), $propertyOP );
        }
        elsif ( $propertyOP =~ /^\s*get|list/i ) {
		    $propertyOP =~ s/^\s*get_\s*//g; $propertyOP =~ s/^\s*list\s*//g;
		if ($propertyOP =~ /;/ ) {
		    @_ = split /;/, $propertyOP ;
		    $rst = &getProperties(&getTCName($tcname), $_[0], $_[1]);
	    	} else {
			    $rst = &getProperties(&getTCName($tcname), $propertyOP, "value" );
		 }
         }
         elsif ( $propertyOP =~ /^\s*create/i ) {
        	$rst = &createPropertyTemplate($tcname);
         }
         elsif ( $propertyOP =~ /^\s*match|filter/i ) {
		    $propertyOP =~ s/^\s*match\s*=//g;
		    $propertyOP =~ /\s*(\S+)\s*[:|;]\s*(\S+)\s*/; 
        	    $rst = &matchProperty($1, $2, $tcname);
         } else {
	    	    $rst = sprintf "ProcessProperty (no match OP) %40s %20s", $tcname, $propertyOP;
    	 }
	    if (($rst) && ($rst =~ /^\s*$/)) { $rst = "_noMatchedPropertyOP_";}
	    if ((defined $prMsg) && ($prMsg ==1)) { print  $rst;}
	    if ($rst) { return $rst; } else { return "doen't exist"; }
}

################################################################################
#	Subroutine Name : matchProperties
#		Function: return true/false 
#	Input Parameters: Property Name in regExp  
#	Output/Returns  : True/False
################################################################################
sub matchProperty { # &matchProperty("QAOwner","ywang", "TC_tc1");
	my $propertyName = ".*"; my $propertyPattern = ".*"; my %array; my $tcname = "TC_tc1";
	$propertyName = shift if (@_);
	$propertyPattern= shift if (@_);
	$tcname = shift if (@_);

	 if (&getProperties(&getTCName($tcname)) =~ /info:There is no/ ) {
		 return "False";
	 }

	foreach my $each (split /\n/,  &getProperties(&getTCName($tcname))) {
		$each =~ /^\s*(\w+)\s*=\s*(\w+)\s*$/;
		$array {$1}  = $2;
	}
	foreach my $each (sort keys %array) {
		if (($array{$each} =~ /$propertyPattern/) && ( $each =~ /$propertyName/)) { 
			 return "True"; }
	}
	return 'False';
}

################################################################################
#	Subroutine Name : getProperties
#		Function: return Test Case Property
#	Input Parameters: Property Name (regExp)  (tcName, tcPattern, value)
#	Output/Returns  : Property Value
################################################################################
sub getProperties() { 	# get TC Property Names	(TH:TC Managements)
	    	my %array; my $returnValue;
		my $tcname 		; $tcname 		= shift if @_ ;
		my $propertyOp		; $propertyOp  		= shift if @_ ;
		my $returnType= 'latest'; $returnType 		= shift if @_ ;

    		$propertyOp =~ s/^\s*add\s*=\s*//ig;
		$propertyOp =~ s/^\s*_eq_\s*//g;
		$propertyOp =~ s/\s*_eq_\s*/=/g;
		$propertyOp =~ s/_column_/:/g;

		if ($propertyOp =~ /_all_/) { $returnType = "_all_"; $propertyOp =~ s/_all_//g; }

    if ( -e  "$tcname\\thProperty.txt" ) { ; } else { return "info:There is no $_[0]/thProperty.txt here";}
    open Fin, "$tcname\\thProperty.txt" || die "Can't open file:$!";
    while ( $_ = <Fin> ) {
	    @_= split /\|/, $_;
	    my $propertyName_ = $_[0]; my $propertyValue_ = $_[1]; $propertyName_ =~ s/^\s*//g; $propertyName_ =~ s/\s*$//g;
	    if (($propertyName_ !~ /^\s*$/) && ( $propertyValue_ !~ /^\s*$/)) {   
 	      	if (($propertyName_ =~ /$propertyOp/i) || ( $propertyOp eq '')) { # PropertyPattern Filter
		   	if ($returnType =~ /^\s*$/) { $returnValue .= sprintf "%-20s=%s\n",$propertyName_, $propertyValue_; 
			} elsif ($returnType =~ /values/i) { 
				$returnValue .= sprintf "%s\n", $propertyValue_;
			} elsif ($returnType =~ /_all_/i) { 
				# $returnValue = sprintf "%-20s=%s\n",$propertyName_, $propertyValue_;
				$propertyValue_ =~ s/^\s*//g;
				$propertyValue_ =~ s/\s*$//g;
				$returnValue = sprintf "\t%s\n", $propertyValue_;
			} elsif ($returnType =~ /history/i) { 
				$returnValue .= sprintf "%-20s=%s\n",$propertyName_, $propertyValue_;
			} elsif ($returnType =~ /\blatest\b/i) {
				$returnValue = "$propertyValue_\n";
			} elsif ($returnType =~ /\bvalue\b/i) {
				$returnValue = sprintf "%s\n", $propertyValue_;
		   	}
		}
		$array{$propertyName_} = $returnValue;
	}
    }
    close Fin;

	$returnValue = "\n";

	if ($returnType =~ /_all_/i) {
		foreach my $each (sort keys %array) { 
			$returnValue .= sprintf "%20s%s", $each, $array{$each}; }
		return $returnValue;
	} else {
		$returnValue =  $array{$propertyOp} ; 
		if ($returnValue ) { $returnValue =~ s/\s*\n\s*$//g; if ($returnValue =~ /^\s*$/) { $returnValue = "_noMatch_";} ; return $returnValue; }
		else { return ""; }
    	}
}

################################################################################
#	Subroutine Name : modfyProperty
#		Function: modify Test Case Property
#	Input Parameters: Test Case Property Name
#	Output/Returns  : updated c:\TC_*\thProperty.txt
#	Subroutine Name : 
#		Function: 
#	Input Parameters: 
#	Output/Returns  : 
################################################################################
sub modifyProperty() { 	# modify TC Property (TH:TC Managements)
    my $tcname       = $_[0];
    my $propertyName = $_[1];
    $propertyName =~ s/^\s*modify\s*=\s*//g;
    $propertyName =~ /(\w+)\s*:\s*(\w+)\s*/;
    $propertyName = $1;
    my $propertyValue = $2;
    my $cmdStr        = "delete=$propertyName";
    &deleteProperty( $tcname, $cmdStr );
    $cmdStr = "add=$propertyName:$propertyValue";
    &addProperty( $tcname, $cmdStr );
    return "$propertyName is modified to $propertyValue for $tcname";
}

################################################################################
#	Subroutine Name : deleteProperty
#		Function: delete Test Case Property
#	Input Parameters: Test Case Property Name
#	Output/Returns  : update c:\TC_*\thProperty.txt
################################################################################
sub deleteProperty() {	# delete TC Property	(TH:TC Managements)
    my $fname = "$_[0]\\thProperty.txt";
    my $fout  = $fname; $fout =~ s/\.txt/_Dumpster\.txt/;

    my $propertyName = $_[1]; 
    if ($propertyName !~ /\s*del\S*\s*=\s*/) { return "Warning: wrong format  -del=prop1;pr2Screen";}
    $propertyName =~ s/^\s*del\S*\s*=\s*//g; $propertyName =~ s/:\s*\S*//;
    my %array ;
    open Fin, "$fname"; @_ = <Fin>; close Fin;

    open Fout, ">>$fout";
    foreach my $each (@_) {
        if ( $each =~ /^\s*$propertyName\s*\|/i ) { print Fout "$each"; }
    }
    close Fout;

    open Fout, ">${fname}" || die "Can't open $fname:$!";
    foreach my $each (@_) {
        if ( $each !~ /^\s*$propertyName\s*\|/i ) {
            print Fout "$each";
        }
    }
    close Fout;
    return "$propertyName is deleted from $fname";

}

################################################################################
#	Subroutine Name : createPropertyTemplate
#		Function: 
#	Input Parameters: 
#	Output/Returns  : 
################################################################################
sub createPropertyTemplate() { 	# create TC Property File (TH:TC Managements)
    my $timeStr = getDate(); $timeStr = "|$timeStr|$timeStr|0:0:0:0s|Comment1|Comment2";
    my $fname = "@_\\thProperty.txt";
    open Fout, ">$fname";
    printf Fout "%20s|%10s%s\n", 'tcId','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcDesc','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcSPR','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcSCR','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'QA','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'modolID','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'priority','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'openSPR','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcID','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcOwner','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcId','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'resultN','null',$timeStr;
    close Fout;
}

################################################################################
#	Subroutine Name : addProperty
#		Function: add Test Case Property
#	Input Parameters: Test Case Property Name
#	Output/Returns  : updated c:\TC_*\thProperty.txt
################################################################################
sub addProperty() { 	# add TC Property (TH:TC Managements)
    my $timeStr = &getDate(); $timeStr = "|$timeStr|$timeStr|0:0:0:0s|comment1|comment2";
    my $fname        = "$_[0]/thProperty.txt";
    my $propertyName = $_[1];

    $propertyName =~ s/^\s*add\s*=//g;
    $propertyName =~ s/^\s*add\s*_eq_\s*//g;
    open Fout, ">>$fname";
    	if ($propertyName =~ /\|/) { # for tcRunResult 
		$propertyName =~ /^\s*(\S+)\s*\|\s*(\S+)\s*\|(.+)\s*$/; 
		my $propName = $1;
		my $propValue = $2;
		my $propComment = $3;
		$propValue =~ s/_space_/ /g;
		$propValue =~ s/_eq_/=/g;
		$propValue =~ s/_column_/:/g;
        	printf Fout "%20s|%10s|%s\n",$propName, $propValue,$propComment;
	} else {
		$propertyName =~ /^\s*(\S+)_column_(\S+)\s*/; 
		my $propName = $1;
		my $propValue = $2;
		if ($propName && $propValue) {
		$propValue =~ s/_column_/:/g;
		$propValue =~ s/_space_/ /g;
		$propValue =~ s/_eq_/=/g;
		$propValue =~ s/___/ /g;
		$propName =~ s/^\s*add\s*=//g;
        	printf Fout "%20s|%10s%s\n",$propName, $propValue,$timeStr;
		}
	}
    close Fout;
    return "$propertyName is added to $fname";
}

sub getGlobalVars { 
	my $return = <<EOF;
	\$c        		= $c
	\$_TAF        		= $_TAF
	\$SvrDrive 		= $SvrDrive
	\$SvrProjName 		= $SvrProjName
 	\$SvrTCName 		= $SvrTCName
 	\$SvrTCNamePattern 	= $SvrTCNamePattern
 	\$SvrTCNameExecPattern	= $SvrTCNameExecPattern
	\$tcOp			= $tcOp
	\$SvrPropNamePattern 	= $SvrPropNamePattern
	\$SvrPropValuePattern 	= $SvrPropValuePattern
	\$pr2Screen           	= $pr2Screen            
	\$tc_pl               	= $tc_pl
	\$tsDriver            	= $tsDriver
	\$web_ui_title        	= $web_ui_title
	\$workingDir          	= $workingDir		
	\$tcIdMin             	= $tcIdMin   
	\$tcPropertyPatternPattern     = $tcPropertyPatternPattern
	\$tcPropertyPatternName = $tcPropertyPatternName
	\$ps1_args              = $ps1_args
	\$sleep4Display         = $sleep4Display
	\$Execution_24_7	= $Execution_24_7
	\$NofExecution		= $NofExecution
	\$ExecutionLength 	= $ExecutionLength
	\$ExecutionType   	= $ExecutionType   
	\$performanceMode 	= $performanceMode
	
EOF
	return $return;
} 
sub setGlobalVars {
	shift;
	@_ = split /;/, shift;
	my $foundMatch = 0;
	foreach my $each (@_) {
		$each =~ /^\s*(\S+)\s*=\s*(\S+)\s*/;
		my $varName = $1; my $varValue = $2;
		if ($varName =~ /SvrDrive/i) 			{ $SvrDrive = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /SvrProjName/i) 		{ $SvrProjName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /SvrTCName\b/i) 		{ $SvrTCName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /SvrTCNamePattern\b/i) 	{ $SvrTCNamePattern = $varValue; $SvrTCNameExecPattern = $SvrTCNamePattern; $foundMatch = 1;}
		elsif ($varName =~ /SvrTCNameExecPattern/i) 	{ $SvrTCNameExecPattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /SvrPropNamePattern\b/i) 	{ $SvrPropNamePattern= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /SvrPropValuePattern/i)  	{ $SvrPropValuePattern= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bDrive\b/i) 		{ $SvrDrive = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bProjName\b/i) 		{ $SvrProjName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTCName\b/i) 		{ $SvrTCName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTCNamePattern\b/i) 	{ $SvrTCNamePattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTCNameExecPattern/i) 	{ $SvrTCNameExecPattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btcOp\b/i) 		{ $tcOp= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bPropNamePattern\b/i)  	{ $SvrPropNamePattern= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bPropValuePattern\b/i)  	{ $SvrPropValuePattern= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\bTestSuit\b/i) 		{ $SvrProjName = $varValue; $foundMatch = 1; $SvrProjName =~ s/\\/\//g; $SvrProjName =~ s/$c\/$_TAF\///;}
		elsif ($varName =~ /\bTestSuite\b/i) 		{ $SvrProjName = $varValue; $foundMatch = 1; $SvrProjName =~ s/\\/\//g; $SvrProjName =~ s/$c\/$_TAF\///;}
		elsif ($varName =~ /\bTCNameFilter\b/i) 	{ $SvrTCNamePattern = $varValue;$foundMatch = 1;}
		elsif ($varName =~ /\bTCNameExecFilter\b/i) 	{ $SvrTCNameExecPattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTestCaseExec\b/i) 	{ $SvrTCNameExecPattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTestCase\b/i) 		{ $SvrTCNamePattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bPropNameFilter\b/i)  	{ $SvrPropNamePattern= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bPropValueFilter\b/i)  	{ $SvrPropValuePattern= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\btsuit\b/i) 		{ $SvrProjName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btname\b/i) 		{ $SvrTCNamePattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bpname\b/i)  		{ $SvrPropNamePattern= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bpvalue\b/i)  		{ $SvrPropValuePattern= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btop\b/i) 			{ $tcOp= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\bts\b/i) 			{ $SvrProjName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btn\b/i) 			{ $SvrTCNamePattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btc\b/i) 			{ $SvrTCNamePattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btne\b/i) 			{ $SvrTCNameExecPattern = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bop\b/i) 			{ $tcOp= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\bpr2Screen\b/i)  		{ $pr2Screen= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bnotUsegetTCName\b/i)  	{ $notUsegetTCName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btc_pl\b/i)     		{ $tc_pl= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btcDriver\b/i)  		{ $tc_pl= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btsDriver\b/i)  		{ $tsDriver = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bweb_ui_title\b/i)  	{ $web_ui_title= $varValue; $foundMatch = 1; $web_ui_title =~ s/___/ /g;}
		elsif ($varName =~ /\bworkingDir\b/i)  		{ $workingDir= $varValue; $foundMatch = 1; $workingDir =~ s/\\/\//g;}
		elsif ($varName =~ /\btcIdMin\b/i)  		{ $tcIdMin = $varValue; $foundMatch = 1;}

		elsif ($varName=~/\btcPropertyPatternPattern\b/i){ $tcPropertyPatternPattern= $varValue; $foundMatch = 1; $tcPropertyPatternPattern =~ s/_pipe_/\|/gi;}
		elsif ($varName =~ /\btcPropertyPatternName\b/i){ $tcPropertyPatternName= $varValue; $foundMatch = 1;}

		elsif ($varName=~/\btcFilterFilter\b/i)		{ $tcPropertyPatternPattern= $varValue; $foundMatch = 1; $tcPropertyPatternPattern =~ s/_pipe_/\|/gi;} # todo
		elsif ($varName =~ /\btcFilterName\b/i)		{ $tcPropertyPatternName= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\btppp\b/i)  		{ $tcPropertyPatternPattern= $varValue; $foundMatch = 1; $tcPropertyPatternPattern =~ s/_pipe_/\|/gi;}
		elsif ($varName =~ /\btppn\b/i){ $tcPropertyPatternName= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\bkeyValue\b/i)  		{ $tcPropertyPatternPattern= $varValue; $foundMatch = 1; $tcPropertyPatternPattern =~ s/_pipe_/\|/gi;}
		elsif ($varName =~ /\bkey\b/i)			{ $tcPropertyPatternName= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\btcFilters\b/i)  		{ 
			$varValue =~ /(.+)_matches_(.+)/; 
			$tcPropertyPatternName    = $1;
			$tcPropertyPatternPattern = $2;
			$foundMatch = 1;
		}

		elsif ($varName =~ /\bps1_args\b/i)		{ $ps1_args             = $varValue; $foundMatch = 1; $ps1_args =~ s/___/ /ig;}
		elsif ($varName =~ /\bsleep4Display\b/i)  	{ $sleep4Display = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btcDelay\b/i)  		{ $sleep4Display = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bc\b/i)  			{ $c		 = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\b_TAF\b/i)  		{ $_TAF		 = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bExecution_24_7\b/i)  	{ $Execution_24_7= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bNofExecution\b/i)  	{ $NofExecution  = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bExecutionLength\b/i)  	{ $ExecutionLength = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bExecutionType\b/i)  	{ $ExecutionType   = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bperformanceMode\b/i)  	{ $performanceMode = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bpm\b/i)  			{ $performanceMode = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bpropertyOp\b/i)  		{ $propertyOp	   = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bpo\b/i)  			{ $propertyOp	   = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btsFilter\b/i)  		{ $tsFilter	   = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bSUTSymbol\b/i)  		{ $SUTSymbol       = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btsFilterDefault\b/i)  	{ $tsFilterDefault = $varValue; $foundMatch = 1;}

	}
	$foundMatch;
}


sub runPowershell {
	my $cmd = shift; 
	if ($cmd =~ /.ps1\s+/) { $cmd = "$cmd"; return `$cmd`;}
	else {
	my $perl = $^X;  $perl =~ s/\\/\\\\/g;
	return `$perl $cmd`;
	}
}


# $foundMatch = 1;
sub generateIndex_pyAnvil_pl {

	my $cwd = $workingDir; my $cmd = $workingDir. "\/index.ps1";

	open Fout, "> ".$cwd."/index_pyAnvil.pl";
print Fout<<EOF_;
############################ index_pyAnvil.pl ###################################
use strict;
&execTC(\$ARGV[0]);

sub execTC {
	my \$passFail='FAIL'; my \$logHtml; my \$logXml	;
	my \$pyAnvil= $c.'/pyAnvil/pyAnvil -s '		;
	my \$tcDir  = "$cwd\/"		;
	my \$testsuiteHook = "index.pl"			; 
	my \$tcId   = -1				; \$tcId   = shift if \@_;
	my \$tcDesc = "Testcase \$tcId Demo"		; \$tcDesc = shift if \@_;
	my \$tsDesc = "pyAnvil Testsuite Demo"		; \$tsDesc = shift if \@_; 

	\$testsuiteHook = \$tcDir.\$testsuiteHook		; 
	my \$tcScenario = "_tc.xml"			; \$tcScenario = \$tcDir."_tc.xml"	; 
	my \$tcLog_pyAnvil = "_tcLogAppend_.txt"         ; \$tcLog_pyAnvil = \$tcDir."\$tcLog_pyAnvil";
	if (\$tcId =~ /^\\s*\$/) { print `\$testsuiteHook`; return 0; }
my \$str=<<EOF;
<?xml version="1.0" encoding="utf-8"?>
<XMLTestCollection>
    <TestList TestCases="\$tcDesc">
	<ToolCase>
	    <Name>\$tcDesc</Name>
	    <Executable>C:/strawberry/perl/bin/perl.exe</Executable>
	    <Parameters>\$testsuiteHook \$tcId</Parameters>
	    <StdoutContains>PASS</StdoutContains>
	</ToolCase>
    </TestList>
</XMLTestCollection>
EOF
	open Fout, ">\$tcScenario"; print Fout \$str; close Fout; my \$cmd = \$pyAnvil."\$tcScenario"; my \$rst = `\$cmd`; 
	foreach my \$each (split /\n/, \$rst) { 
		if (   \$each =~ /^\\s+PASS\\s+/)     { \$passFail = "PASS";}
		elsif (\$each =~ /^\\s+FAIL\\s+/)     { \$passFail = "FAIL";}
		elsif (\$each =~ /^\\s+XML:\\s+(.+)/) { \$logXml   = \$1;}
		elsif (\$each =~ /^\\s+HTML:\\s+(.+)/){ \$logHtml  = \$1;}
	}
open Fout, "> \$tcLog_pyAnvil "; print Fout "\$rst\n"; close Fout;  print "- > \$tcLog_pyAnvil\n"; 
	print "\$passFail\n"; 
}
############################ index_pyAnvil.pl ###################################
EOF_
	close Fout; print    "  -->".$cwd."/index_pyAnvil.pl\n";

}

sub generateGenerateTestsuite {
	my $cwd = $workingDir; $cwd = shift if @_;
	open Fout, "> ".$workingDir."/generateTestsuite.pl";
print Fout<<EOF;
\$cmd = "$c/$_TAF/taf.pl web_ui_title=MV___SDK___PROXY___(Please___connect___to___Intel___Network);tsDriver=$cwd/index.pl;printVars;generateTestsuite"; `\$cmd`;
EOF
	close Fout;
}

sub generateIndex_pl {
	my $cwd = $workingDir; $cwd = shift if @_;
	open Fout, "> ".$cwd."/index.pl";
print Fout<<EOF_;

##################### index.pl for pyAnvil ############################
my \$testsuiteHook = "powershell -executionpolicy unrestricted -file $cwd/index.ps1 $ps1_args";


if    (\$ARGV[1]) { print &call_index(\$ARGV[0], "noExec") ;	}  
elsif (\$ARGV[0]) { print &call_index(\$ARGV[0], "yesExec");    }
else             { print &call_index();                         }


sub call_index { 		my \$return ; my \$recordCtr=1;
	if (\@_) {;} else {; return `\$testsuiteHook`;}
	my \$indexCtr = 9999	; \$indexCtr = shift if \@_; 		 
	my \$execYN   = 'noExec' ; \$execYN   = shift if \@_; 
	\@_ = (split /\\n/, `\$testsuiteHook`) ;


	foreach \$each (\@_) { 
		if ((\$each) && (\$each =~ /^\\s*_/)) { \$return = \$return .\$each."\n";
		} elsif ((\$each) && (\$each !~ /^\\s*_/)) {
			\$return = \$return . sprintf "TC [%04s] %s\\n",\$recordCtr,\$each; 
			if ((\$recordCtr == \$indexCtr ) && ( \$execYN =~ /noExec/i )) { return "TC [\$recordCtr]       \$each"; } 
			if ((\$recordCtr == \$indexCtr ) && ( \$execYN =~ /yesExec/i)) { return `\$testsuiteHook \$indexCtr `  ; } 
			\$recordCtr++;
	  	} 
 	} 
	if (\$return =~ /pass/i) { return 0;} 
	if (\$return =~ /fail/i) { return 1;} 
}

##################### index.pl for pyAnvil ############################
EOF_
	close Fout; print    "  -->".$cwd."/index.pl\n";


}

sub generatePerl_pl_template {
	my $cmd = $workingDir; 
	open Fout, "> $cmd/index.pl";
	my $tsNameTmp =	&getRoot($cmd);
print Fout<<EOF_;
if (\$ARGV[0]) { 
	if (\$ARGV[0] == 1) { print "pass"; } # <<< plug in the test case 1 here e.g. print `index.pl 1` ; >>>
	if (\$ARGV[0] == 2) { print "pass"; } # <<< plug in the test case 2 here e.g. print `index.pl 2`>>>
	if (\$ARGV[0] == 3) { print "pass"; } # <<< plug in the test case 3 here e.g. print `index.pl 3`>>>
	if (\$ARGV[0] == 4) { print "pass"; } # <<< plug in the test case 4 here e.g. print `index.pl 4`>>>
	if (\$ARGV[0] == 5) { print "pass"; } # <<< plug in the test case 5 here e.g. print `index.pl 5`>>>
	if (\$ARGV[0] == 6) { print "pass"; } # <<< plug in the test case 6 here e.g. print `index.pl 6`>>>
} else {
print \<\<EOF;
1. Test case description 1 for testing the function 1 --- Please modifyaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
2. Test case description 2 for testing the function 2 --- Please modifybbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
3. Test case description 3 for testing the function 3 --- Please modifycddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
4. Test case description 4 for testing the function 4 --- Please modify
5. Test case description 5 for testing the function 5 --- Please modify
6. Test case description 6 for testing the function 6 --- Please modify
EOF
;
}
__END__

EOF_
	close Fout;
	print "\n[Warning] Creating Temporial testsuite hook --> [".$workingDir."/index.pl]\n"; ; 

#_testsuiteName_: $tsNameTmp
#_testdriverName_: $tsDriver

}

sub generateTestsuite { 						# Generating 1. index.pl 2. index.pl + index_pyAnvil.pl 
	my $cmd = $workingDir;  $cmd = shift if @_;
	my $cwd = $cmd;
	if (-e "$cmd\/index.ps1") { $cmd = $cmd . "\/index.ps1";	#### pre-existing testsuiteHook is index.ps1 
		&generateIndex_pyAnvil_pl($cwd)			  ; 	# --> generate index_pyAnvil.pl 
		&generateIndex_pl ($cwd)			  ; 	# --> generate index.pl 
		}
	elsif (-e "$cmd\/index.pl")     { 
		$cmd = $cmd . "\/index.pl";}	#### pre-existing testsuiteHook is index.pl 
	else  { 							####  No pre-existing index.pl 
		if ($tsDriver =~ /null/i) { $tsDriver = "$cmd\/index.pl"; }	
		&generatePerl_pl_template();
	}								

	##############################################  subroutine Main ###########################################
	$cmd = shift if @_; my $testsuiteName="_default_testsuiteblas_"; my $testsuitePropertyFName='tsProperty.txt'; my $testDriverName = $cmd; 
	my $tsPropertyStr = "web_ui_title: "; my $tcCtr=1; my $TAF= $SvrDrive ;

	$testsuiteName = &getRoot_4($cwd);  			############ $testsuiteName = &getRoot(&getcwd());  


	############ Generate Property file for webUI tc description
 	if ($cmd =~ /\.ps1\s*$/) { $cmd = "powershell -executionpolicy unrestricted -file ". $cmd. " $ps1_args"; }


	foreach my $each (split "\n", &runPowershell($cmd)) {	# get testsuiteName _testsuitename_: (\w+)and _testdrivername_: (\w+)
		if    ($each =~ /_testsuitename_/i)  { $each =~ /_testsuitename_\s*:\s*(.+)\s*$/i;  $testsuiteName  = $1; if ($testsuiteName =~ /\s/) { print "white space in testsuitename\n";exit; }}
		elsif ($each =~ /_testdrivername_/i) { $each =~ /_testdrivername_\s*:\s*(.+)\s*$/i; $testDriverName = $1; }
		else { ; }
	}

print<<EOF;
  <--$cmd       _testsuitename_ : [$testsuiteName] 
  <--$cmd       _testdrivername_: [$testDriverName] 
  <--$cmd       Generating $c/$_TAF/$testsuiteName ...... (Can take several minutes)
EOF

	if ($web_ui_title =~ /Test Automation Framework/) {$tcCtr=1; $tsPropertyStr = $tsPropertyStr . " $testsuiteName : web_ui_title\n";} # overwrite web_ui_title 
	else {$tcCtr=1; $tsPropertyStr = $tsPropertyStr . " $web_ui_title: web_ui_title\n";}

	foreach my $each (split "\n", &runPowershell($cmd)) { # get testsuitePropertyString
		if    ($each =~ /_testsuitename_/i)  { $each =~ /testsuitename_\s*:\s*(.+)\s*$/i;	$testsuiteName  = $1; }
		elsif ($each =~ /_testdrivername_/i) { $each =~ /testdrivername_\s*:\s*(.+)\s*$/i; 	$testDriverName = $1; }
		elsif ($each =~ /^\s*\n/i) { ; }
		elsif ($each =~ /^\s*$/i) { ; }
		else { $tsPropertyStr = $tsPropertyStr . sprintf "$c/$_TAF\/$testsuiteName\/testcase%04d\|%4d  %s\n", $tcCtr, $tcCtr, $each; $tcCtr++;} 
	}
	############ Generate Property file for webUI tc description

	############ add tcDesc Property #############

	my $tcCtr_ = 0;
	foreach my $each (split "\n", &runPowershell($cmd)) { # get testsuitePropertyString
		if    ($each =~ /_testsuitename_/i)  { $each =~ /testsuitename_\s*:\s*(.+)\s*$/i;	$testsuiteName  = $1; }
		elsif ($each =~ /_testdrivername_/i) { $each =~ /testdrivername_\s*:\s*(.+)\s*$/i; 	$testDriverName = $1; }
		elsif ($each =~ /^\s*\n/i) { ; }
		elsif ($each =~ /^\s*$/i) { ; }
		else { 
			$each =~ s/\s/_space_/g;
			$each =~ s/:/_column_/g;
			$each =~ s/=/_eq_/g;
			$tcDesc[$tcCtr_] = $each; $tcCtr_ ++; 
			$propertyOp = "tcDescAuto";
		} 
	}

	############ add tcDesc Property #############

	############ Create Testsuite/Testcase
	$tcCtr=1;
	foreach my $each (split "\n", &runPowershell($cmd)) { # get testsuitePropertyString
		if    ($each =~ /_testsuitename_/i)  { $each =~ /testsuitename_\s*:\s*(.+)\s*$/i;	$testsuiteName  = $1; }
		elsif ($each =~ /_testdrivername_/i) { $each =~ /testdrivername_\s*:\s*(.+)\s*$/i; 	$testDriverName = $1; }
		elsif ($each =~ /^\s*\n/i) { ; }
		elsif ($each =~ /^\s*$/i) { ; }
		else { 
			if ($tsDriver !~ /null/) { $testDriverName = $tsDriver; } # tsDriver overwrite testDriverName
			my $ps1_args_ = $ps1_args; $ps1_args_ =~ s/ /___/g;
			my $cmd = sprintf "ps1_args=$ps1_args_;testsuit=$testsuiteName;create=testcase%04d/customTC:${testDriverName}_space_${tcCtr}:customTC\n", $tcCtr++  ; 
			&processTCs("",$cmd);
		}
	}

	############ Create Testsuite/Testcase
	open Fout, ">>$c/$_TAF/$testsuiteName/$testsuitePropertyFName" || die "Can't create file\n"; print Fout $tsPropertyStr; close Fout;
	print    "  -->$c/$_TAF/$testsuiteName/$testsuitePropertyFName\n";
	&generateGenerateTestsuite(); 
	print    "  -->$c/$_TAF/$testsuiteName/generateTestsuite\n";
			$cmd = sprintf "tcDelay=0;testsuite=$testsuiteName;list"; 
			&processTCs("",$cmd);
	&generateRootIndex();
	if ($interact =~ /\by\b/) {system ("C:/Program Files/Internet Explorer/iexplore.exe", "$c/$_TAF/$testsuiteName/index.htm");}
	print "\n";
}


sub help {
if ( $^O =~ /MSWin32/ ) {; } else { print "TAF supports Win32 ONLY currently.\n"; exit; }
	&genDriver_taf_pl ();

my $help=<<EOF;
-----------------------------------------------------------------------------------------------------------------------
	Test::AutomationFramework - Test Automation Framework  (TAF)	version: $VERSION

	TAF manages automated test cases regarding test setup, test query, test execution and 
	test reportings with *ONE* mouse-click. No programming and no manual Reading.

	TAF Test Case integration - $c/$_TAF/[test_suite]/[test_case]/tc.pl
				
			* $c/$_TAF/[test_suite]/[test_case]/tc.pl  : print Pass|fail|number to STDOUT
			* $c/$_TAF/[test_suite]/[test_case]/tc.pl  : geneate TC Log as cwd()/_appendLog.txt 

	TAF Test Suite integration - $c/$_TAF/[test_suite]/index.pl or index.ps1

			* $c/$_TAF/index.[pl|ps1]             : print one TC Description per line
			* $c/$_TAF/index.[pl|ps1] Index       : exec Index-th TC

  	[Web Access: http://$c/$_TAF/index.htm]
	1. Install StrawberryPerl 
	2. Install TAF from CPAN                 (Perl -MCPAN -e "install Test::AutomationFramework)
	3. Install TAF Testbed                           (Perl -MTest::AutomationFramework -e "help"   
	4. *One* mouse click to execute and view test results in the Test Bed

	[Web examples]
	5. Add test suite by modifying $c/$_TAF/taf.bat 
	6. Add test case by modifying $c/$_TAF/[test_suite]/[test_case]/tc.pl 
	7. Run $c/$_TAF/taf.bat to create user's test suite structure and start its webUI

	webUI TAF usages scenarios:  	
		List Test cases:		
			* list test pass|fail                                     (click Pass|Fail) 
			   cmd>taf.pl testsuite=_testsuit2_;list
			* list Passed test cases                               (click title's Pass)
			   cmd>taf.pl testsuite=_testsuit2_;tcFilters=tcRunResult_matches_pass 
			* list Failed test cases                             (click title's Failed)
			   cmd>taf.pl testsuite=_testsuit2_;tcFilters=tcRunResult_matches_fail
			* list non-Pass|Failed test cases          (click \| between Pass and Fail) 
			   cmd>taf.pl testsuite=_testsuit2_;tcFilters=tcRunResult_matches_null
		Exec Test cases:		
			* Exec test cases 		      	  	  (click pass|fail counters)
			   cmd>taf.pl testsuite=_testsuit2_;testcase=testcase0001;exec
			   cmd>taf.pl testsuite=_testsuit2_;testcase=testcase000[1,2,3,4];exec
			   cmd>taf.pl testsuite=_testsuit2_;testcase=testcase000[1-9];exec
			* Exec test suite 		            (click title pass|fail counters)
			   cmd>taf.pl testsuite=_testsuit2_;exec
		View Test Results
			* View historical pass/fail 	                           (click Pass|Fail) 
			* View historical logs		                           (click Test Desc) 
			* View historical pass/fail in graphics 		(click title Result)

	[Programmer's Usage: from command line. see TAF commands cmd> and taf cmds in $c/$_TAF/taf.bat>]

		Create Testcases		
			* c:\\_TAF\\taf.pl -processTSs create=c:/_TAF/_testsuiteTestBed/_testsuite4_
		Create Testsuites
			* c:\\_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase2_/overwrite,perf,sleep=3
			* c:\\_TAF\\taf.pl testsuit=_testsuite2_;create=_testcase1_/overwrite,sleep=20
			* c:\\_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase6_/overwrite,genLog,sleep=10
			* c:\\_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase9_/overwrite,expectedFail,genLog,sleep=1
			
		TC Execution controls
		
			* tcIdMin			: start TC Id for Testsuite Execution (default = 0)
			* printVars			: Print Global Variables
			* printTCFilters		: print TC Filters 
			* setTCFilter			: set_property1_as_value1[_doit_]
			* getTCFilter			: get_property
			* tcFilters			: =property_match_propertyvalue
			* tsDriver			: Testsuite Driver|hook
			* web_ui_title			: set webUI title
			* Execution_24_7		: Continuous execution [y|n]
			* NofExecution			: Number of Executions
			* ExecutionDuration		: Execution Longivity
			* exitTAF			: exitTAF gracefully
			* executionType			: TC|TS
			* performanceMode		: 'slow' for webUI & 1st time execution. 'fast' for command line exec 

-----------------------------------------------------------------------------------------------------------------------

	[Examples]
	$c\\$_TAF\\taf.pl genDriver
	$c\\$_TAF\\taf.pl generateIndex_pl | generateIndex_pyAnvil_pl
	$c\\$_TAF\\taf.pl generateTestsuite
	$c\\$_TAF\\taf.pl tsDriver=$c/TAF_pyAnvil/index_pyAnvil.pl;web_ui_title=Test___Automation___Framework;printVars;generateTestsuite 	Generate pyAnvil Testsuite

	$c\\$_TAF\\taf.pl tcIdMin=5;printVars;testsuite=_testsuite3_;list 
	$c\\$_TAF\\taf.pl tcPropertyPatternPattern=fail;tcPropertyPatternName=tcRunResult;testsuite=_testsuite3_

	[TAF Execution Controls]
	$c\\$_TAF\\taf.pl -help 
	$c\\$_TAF\\taf.pl tcPropertyPatternPattern=\\d+_pipe_null;tcPropertyPatternName=tcRunResult;testsuite=_testsuite3_  rem list tcRunResult =~ /performance|null/
	$c\\$_TAF\\taf.pl -processTSs [create|delete|add]=$c/_testsuite1/_testsuite2
	$c\\$_TAF\\taf.pl Execution_24_7=y;NofExecution=5;Execution=24hour;testsuite=_MV_SDK_OCSP;[list|exec]
	$c\\$_TAF\\taf.pl testsuit=CPD_QA_Tests/BATtests/MVTests/Bat/MV_2-0-1-0057/_MV_SDK_OCSP;list
	$c\\$_TAF\\taf.pl exitTAF
	$c\\$_TAF\\taf.pl ExecutionType=[runTC|runTS]
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;performanceMode=fast;list
	$c\\$_TAF\\taf.pl [SUTSymbol|tsFilterDefault]=_;tsFilter="2.2.0.217[_doit_];scanTestsuites 
	$c\\$_TAF\\taf.pl generateRootIndex
	$c\\$_TAF\\taf.pl -processTCs create=tc1/fail,overwrite
	$c\\$_TAF\\taf.pl -processTCS tsDriver=index_pyAnvil.pl;printVars;testsuite=_testsuite3_;list

	#####################  get/set tc [Property|Filter]  ##################################
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=set_property1_[as|eq]_propVal1[_doit_]
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=_get_property1[_doit_]
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=_get__all_[_doit]

	##################### TC [list|exec] based on TC Filters ##################################
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;listTcfilters
		taf.pl testsuite=_testsuite2_;pm=fast;tcOp=listtcfilters
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;tcFilters=testproperty_matches_tsetProperValue1;[list|exec]		

	e.g. 
		1. taf.pl testsuite=_testsuite2_;[list|print]Tcfilters
		2. taf.pl testsuite=_testsuite2_;propertyOP=_set_property1_[as|eq]_propVal1_doit_
		3. taf.pl testsuite=_testsuite2_;propertyOP=_get_property1
		4. taf.pl testsuite=_testsuite2_;tcFilters=property1_matches_PropertyValue1;[list|exec]		
-----------------------------------------------------------------------------------------------------------------------
EOF
	print $help;
	&genDriver();
}
sub helpmore {
my $help=<<EOF;
-----------------------------------------------------------------------------------------------------------------------

---------------- This help is for historical and under-development functions -----------------
taf.pl testsuit=_ts1_;list 
taf.pl testsuit=_ts1_;testcase=_tc1_;list 


taf.pl  -processTC or -tc arg=[tcName;cmd] create=tc1|list|get|exec=tc1|detect|delete|log|getLogName|printResult;all

	# e.g.  taf.pl -tc create=tc1;fail,overwrite
	        taf.pl -tc create=tc1;fail,genLog;pr2Screen
	        taf.pl -tc create=tc1;performanceTC,genLog;pr2Screen
	        taf.pl -tc delete=tc1;pr2Screen

	-processTCs or -s  arg=[TCOP=list;...]  # e.g.  taf.pl -s TCNamePattern=tc.*
	                                 	#       taf.pl -s list
		Drive=c:;			# c: d: e: ...
		TestSuite=_testSuit_;		# directory 
		TCOp=list;			# List test cases that matches the TCNameFilter and PropertyFilter
		TCName=_testCase_;		# test case name 
		TCNamePattern=*;		# Test Case Name Filter 
		TCNameFilter=*;			# Test Case Name Filter 
		PropNameFilter=.*;		# Property_Name Filter
		PropValueFilter.=.*;		# Property_Value Filter
		pr2Screen;			# Results will be displayed on screen 
		getVars|listVars|printVars	# get or print TAF settings

        -processTSs [create|delete|add]=c:/... 
	-processProperty or -prop arg=[add=prop1:val1]  add|delete|list|get|modify|match|filter

	# e.g   taf.pl -prop list=tc;pr2Screen
	        taf.pl -prop add=prop1:val1;pr2Screen
	        taf.pl -prop match=.*:.*;pr2Screen
	        taf.pl -prop match=propNameFilter:propValFilter

	To create driver (taf.pl): perl.pl -MTest::AutomationFramework -e "help" 

	taf.pl -processTCs create=tc1/fail,overwrite
	taf.pl -processTCS tsDriver=index_pyAnvil.pl;printVars;testsuite=_testsuite3_;list
	$c\\$_TAF\\taf.pl  tsDriver=index_pyAnvil.pl;printVars;generateTestsuite
	$c\\$_TAF\\taf.pl  web_ui_title=testtitle;printVars;generateTestsuite
	cwd/taf.pl generateTestsuite 
	taf.pl generateRootIndex
	$c\\$_TAF\\taf.pl workingDir=c:/_MahoBby_/CPD_QA_Tests/BATtests/MVTests/Bat/MV_2-0-1-0062/_MV_SDK_OCSP;web_ui_title=c:/_MahoBby_/CPD_QA_Tests/BATtests/MVTests/Bat/MV_2-0-1-0062/_MV_SDK_OCSP;ps1_args=-buildpath___c:/_MahoBay_/CPD_QA_Tests/BATTests/MVTests/Bat/;generateTestsuite
	$c\\$_TAF\\taf.pl -scanTestsuites Tests/BATtests/MVtests/Bat/2.2.0.217_doit_

	########################## Property add/get ##################################
	taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=set_property1_[as|eq]_propVal1_doit_
	taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=_get_property1_doit_
	taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=_get__all__doit

		taf.pl testsuite=_testsuite3_;testcase=testcase1;propertyOp=add_eq_prop1_column_val1[_doit_]
		taf.pl testsuite=_testsuite3_;testcase=testcase1;propertyOp=add_eq_tcDesc_column_TCDescription___Test[_doit_]
		taf.pl testsuite=_testsuite2_;pm=fast;propertyOp=get_eq_prop1_doit_
		taf.pl testsuite=_testsuite2_;pm=fast;propertyOp=get_eq_tcDesc_doit_
		taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=get_eq_.*_all__doit_
		taf.pl testsuite=_testsuite2_;pm=fast;propertyOP=get_eq_tcOwner_doit_

	##################### TC Property Filter for TC Execution ##################################
	taf.pl testsuite=_testsuite2_;pm=fast;listTcfilters
		taf.pl testsuite=_testsuite2_;pm=fast;tcOp=listtcfilters
	taf.pl testsuite=_testsuite2_;pm=fast;tcFilters=testproperty_matches_tsetProperValue1;[list|exec]		
		taf.pl testsuite=_testsuite2_;pm=fast;tcPropertyPatternName=prop1;tcPropertyPatternPattern=val1;list
		taf.pl testsuite=_testsuite2_;pm=fast;tppn=prop1;tppp=val1;list
		taf.pl testsuite=_testsuite2_;pm=fast;key=prop1;keyValue=val1;list

	e.g. 
		1. taf.pl testsuite=_testsuite2_;listTcfilters
		2. taf.pl testsuite=_testsuite2_;propertyOP=_set_property1_[as|eq]_propVal1_doit_
		3. taf.pl testsuite=_testsuite2_;propertyOP=_get_property1
		4. taf.pl testsuite=_testsuite2_;tcFilters=property1_matches_PropertyValue1;[list|exec]		


	taf.pl install (obsoleted)


-----------------------------------------------------------------------------------------------------------------------
EOF
	print $help;
}
sub genDriver_taf_pl {
	if (-e "$c/$_TAF/taf.pl") {;} else {
	mkpath "$c/$_TAF";
	open Fout, ">$c/$_TAF/taf.pl";
	print Fout &prDriver(1);
	close Fout;
	print " --> $c/$_TAF/taf.pl\n";
	}
}
sub genDriver {
	if ($workingDir =~ /\w+:[\/|\\]\s*$/) { print 'Please do *NOT* run perl -MTest::AutomationFramework -e "install" from rootDir. Run it from a directory.'; exit}
	mkpath  $SvrDrive ;
	if (-e "$c/$_TAF/taf.pl") {;} else {
	open Fout, ">$c/$_TAF/taf.pl";
	print Fout &prDriver(1);
	close Fout;
	print " --> $c/$_TAF/taf.pl\n";
	}
	if (-e "$c/$_TAF/taf.bat") {;} else {
my $str =<<EOF;
REM create test_suit hooks
$c\\$_TAF\\taf.pl -processTSs create=$c/$_TAF/_testsuiteTestBed/_testsuite1_/_TS1
$c\\$_TAF\\taf.pl -processTSs create=$c/$_TAF/_testsuiteTestBed/_testsuite1_/_TS2
$c\\$_TAF\\taf.pl -processTSs create=$c/$_TAF/_testsuiteTestBed/_testsuite2_/_TS1
$c\\$_TAF\\taf.pl -processTSs create=$c/$_TAF/_testsuiteTestBed/_testsuite2_/_TS2
$c\\$_TAF\\taf.pl -processTSs create=$c/$_TAF/_testsuiteTestBed/_testsuite3_
$c\\$_TAF\\taf.pl -processTSs create=$c/$_TAF/_testsuiteTestBed/_testsuite4_

$c\\$_TAF\\taf.pl workingDir=c:/_TAF/_testsuiteTestBed/_testsuite1_/_TS1;generateTestsuite 
$c\\$_TAF\\taf.pl workingDir=c:/_TAF/_testsuiteTestBed/_testsuite2_/_TS1;generateTestsuite 


REM create test_suit (test_suit)/test_case (tc) 
$c\\$_TAF\\taf.pl testsuit=_testsuite2_;create=_testcase1_/overwrite,sleep=20
$c\\$_TAF\\taf.pl testsuit=_testsuite2_;create=_testcase2_/overwrite,sleep=20
$c\\$_TAF\\taf.pl testsuit=_testsuite2_;create=_testcase3_/overwrite,sleep=40
$c\\$_TAF\\taf.pl testsuit=_testsuite2_;create=_testcase4_/overwrite,sleep=30
$c\\$_TAF\\taf.pl testsuit=_testsuite2_;create=_testcase5_/overwrite,sleep=20
$c\\$_TAF\\taf.pl testsuit=_testsuite2_;create=_testcase6_/overwrite,sleep=20
$c\\$_TAF\\taf.pl testsuit=_testsuite1_;create=_testcase1_/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuit=_testsuite1_;create=_testcase2_/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuit=_testsuite1_;create=_testcase3_/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuit=_testsuite1_;create=_testcase4_/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuit=_testsuite1_;create=_testcase5_/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuit=_testsuite1_;create=_testcase6_/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase1_/overwrite,sleep=2

REM performance test 
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase2_/overwrite,perf,sleep=3
REM Failed Functional test 
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase3_/overwrite,fail,sleep=1
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase4_/overwrite,sleep=2
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase5_/overwrite,fail,sleep=4
REM functional test /w log
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase6_/overwrite,genLog,sleep=10
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase7_/overwrite,fail,genLog,sleep=1
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase8_/overwrite,pass,genLog,sleep=1
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;create=_testcase9_/overwrite,expectedFail,genLog,sleep=1

$c\\$_TAF\\taf.pl printTestBedProperties


REM exec all test_suit under test_suit (test_suit)

$c\\$_TAF\\taf.pl testsuit=_testsuite1_;exec
$c\\$_TAF\\taf.pl testsuit=_testsuite1_;testcase=*;exec
$c\\$_TAF\\taf.pl testsuit=_testsuite1_;testcase=testcase1*;exec

$c\\$_TAF\\taf.pl testsuit=_testsuite2_;exec
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;exec


REM Test the tcFilter functions
rem $c\\$_TAF\\taf.pl testsuite=_testsuite3_;printTCFilters
rem $c\\$_TAF\\taf.pl testsuite=_testsuite3_;propertyOp=set_propverty1_as_value1_doit_
rem $c\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase2;propertyOp=set_property1_as_value2_doit_
rem $c\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase2;printTCFilters

rem $c\\$_TAF\\taf.pl testsuite=_testsuite3_;printTcFilters
rem $c\\$_TAF\\taf.pl testsuite=_testsuite3_;propertyOP=get_property1
rem $c\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase2 propertyOP=get_property1

$c\\$_TAF\\taf.pl testsuit=_testsuite4_;create=testcase0001/overwrite,sleep=1,customTC:taftestcase1:customTC
$c\\$_TAF\\taf.pl testsuit=_testsuite4_;create=testcase0002/overwrite,sleep=1,customTC:taftestcase2:customTC
$c\\$_TAF\\taf.pl testsuit=_testsuite4_;create=testcase0003/overwrite,sleep=1,customTC:taftestcase3:customTC
$c\\$_TAF\\taf.pl testsuit=_testsuite4_;create=testcase0004/overwrite,sleep=1,customTC:taftestcase4:customTC
$c\\$_TAF\\taf.pl testsuit=_testsuite4_;exec


REM Setting the moving bar for showing test-in-prog status
$c\\$_TAF\\taf.pl testsuit=_testsuite1_;
$c\\$_TAF\\taf.pl testsuit=_testsuite2_;
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;updateWeb_=_testcase1_/2
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;updateWeb_=_testcase2_/1
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;updateWeb_=_testcase3_/3
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;getWeb_=_testcase1_
$c\\$_TAF\\taf.pl delete=$c/$_TAF/_test_suit1_

REM taf.pl 'testsuit=_test_suit1_;create=_testcase1_/overwrite,customTC:$c/tmp/purge.pl_space_1:customTC'
REM taf.pl 'testsuit=_test_suit1_;create=_testcase1_/overwrite,pyAnvil,customTC:$c/tmp/indexPyAnvil.pl_space_1:customTC'
\@start "" /b "C:\\Program Files\\Internet Explorer\\iexplore.exe" "C:\\$_TAF\\_testsuite3_\\index.htm"
rem todo: property operation and property filter

EOF
	open Fout, "> $c/$_TAF/taf.bat"; print Fout $str; close Fout; print " --> $c/$_TAF/taf.bat\n"; my $cmd = "$c/$_TAF/taf.bat"; system $cmd;
	}
	1;
}

# install is replaced by genDriver () . it is kept for backwards compatible
sub install 		
{
	if ($workingDir =~ /\w+:[\/|\\]\s*$/) { print 'Please do *NOT* run perl -MTest::AutomationFramework -e "install" from rootDir. Run it from a directory.'; exit}
	if (-e "$c\\$_TAF\\taf.pl") {;} else { open Fout, ">$c\\$_TAF\\taf.pl"; print Fout &prDriver(1); close Fout; print " --> $c\\$_TAF\\taf.pl\n"; }
	if (-e "$c\\$_TAF\\taf.bat") {;} else {
my $str =<<EOF;
REM create test_suit (test_suit)/test_case (tc) 
$c\\$_TAF\\taf.pl testsuit=_test_suit2_;create=_testcase1_/overwrite  
$c\\$_TAF\\taf.pl testsuit=_test_suit2_;create=_testcase2_/overwrite
$c\\$_TAF\\taf.pl testsuit=_test_suit2_;create=_testcase3_/overwrite
$c\\$_TAF\\taf.pl testsuit=_test_suit2_;create=_testcase4_/overwrite
$c\\$_TAF\\taf.pl testsuit=_test_suit2_;create=_testcase5_/overwrite
$c\\$_TAF\\taf.pl testsuit=_test_suit2_;create=_testcase6_/overwrite
$c\\$_TAF\\taf.pl testsuit=_test_suit1_;create=_testcase1_/overwrite
$c\\$_TAF\\taf.pl testsuit=_test_suit1_;create=_testcase2_/overwrite
$c\\$_TAF\\taf.pl testsuit=_test_suit1_;create=_testcase3_/overwrite
$c\\$_TAF\\taf.pl testsuit=_test_suit1_;create=_testcase4_/overwrite
$c\\$_TAF\\taf.pl testsuit=_test_suit1_;create=_testcase5_/overwrite
$c\\$_TAF\\taf.pl testsuit=_test_suit1_;create=_testcase6_/overwrite
$c\\$_TAF\\taf.pl testsuit=_test_suit3_;create=_testcase1_/overwrite

REM performance test 
$c\\$_TAF\\taf.pl test_suit=_test_suit3_;create=_testcase2_/overwrite,perf
REM Failed Functional test 
$c\\$_TAF\\taf.pl testsuit=_test_suit3_;create=_testcase3_/overwrite,fail
$c\\$_TAF\\taf.pl testsuit=_test_suit3_;create=_testcase4_/overwrite
$c\\$_TAF\\taf.pl testsuit=_test_suit3_;create=_testcase5_/overwrite,fail
REM functional test /w log
$c\\$_TAF\\taf.pl testsuit=_test_suit3_;create=_testcase6_/overwrite,genLog
$c\\$_TAF\\taf.pl testsuit=_test_suit3_;create=_testcase7_/overwrite,fail,genLog
$c\\$_TAF\\taf.pl testsuit=_test_suit3_;create=_testcase8_/overwrite,fail,genLog

$c\\$_TAF\\taf.pl printTestBedProperties

REM exec all test_suit under test_suit (test_suit)
$c\\$_TAF\\taf.pl testsuit=_test_suit1_;exec
$c\\$_TAF\\taf.pl testsuit=_test_suit1_;testcase=*;exec
$c\\$_TAF\\taf.pl testsuit=_test_suit1_;testcase=testcase1*;exec

$c\\$_TAF\\taf.pl testsuit=_test_suit2_;exec
$c\\$_TAF\\taf.pl testsuit=_test_suit3_;exec

REM Seting the moving bar for showing test-in-prog status
$c\\$_TAF\\taf.pl testsuit=_test_suit1_;list
$c\\$_TAF\\taf.pl testsuit=_test_suit2_;list
$c\\$_TAF\\taf.pl testsuit=_test_suit3_;list
$c\\$_TAF\\taf.pl testsuit=_test_suit3_;updateWeb_=_testcase1_/2,0
$c\\$_TAF\\taf.pl testsuit=_test_suit3_;updateWeb_=_testcase2_/1,1
$c\\$_TAF\\taf.pl testsuit=_test_suit3_;updateWeb_=_testcase3_/3,2
$c\\$_TAF\\taf.pl delete=$c/$_TAF/_test_suit1_

REM taf.pl 'testsuit=_test_suit1_;create=_testcase1_/overwrite,customTC:$c/tmp/purge.pl_space_1:customTC'
rem todo: property operation and property filter
\@start "" /b "C:\\Program Files\\Internet Explorer\\iexplore.exe" "C:\\$_TAF\\_test_suit3_\\index.htm"

EOF
	open Fout, ">$c\\$_TAF\\taf.bat"; print Fout $str; close Fout; print " --> $c\\$_TAF\\taf.bat\n"; my $cmd = $c.'\\'.$_TAF.'\\taf.bat'; system $cmd;
	}
1;
}


sub printTestBedProperties {
	############ Generate taf Property file for _testsuite3_
open Fout, ">$c/$_TAF/_testsuite3_/tsProperty.txt";
my $str = <<EOF;
web_ui_title: Test Automation Framework : web_ui_title
$c/$_TAF/_testsuite3_/_testcase1_| 1  Test case 1 description                            Manual edit please     
$c/$_TAF/_testsuite3_/_testcase2_| 2  Test case 2 Perform TC  for tsProperty.txt         Manual edit please     
$c/$_TAF/_testsuite3_/_testcase3_| 3  Test case 3 Fail TC     for .. tsProperty.txt      Manual edit please     
$c/$_TAF/_testsuite3_/_testcase4_| 4  Test case 4 Pass TC     for ... tsProperty.txt     Manual edit please     
$c/$_TAF/_testsuite3_/_testcase5_| 5  Test case 5 Fail TC     for .... tsProperty.txt    Manual edit please     
$c/$_TAF/_testsuite3_/_testcase6_| 6  Test case 6 TC /w Log   for ..... tsProperty.txt   Manual edit please     
$c/$_TAF/_testsuite3_/_testcase7_| 7  Test case 7 _Expected_Fail_ for ... tsProperty.txt Manual edit please     
$c/$_TAF/_testsuite3_/_testcase8_| 8  Test case 8 _Expected_Fail_ for ... tsProperty.txt Manual edit please     
$c/$_TAF/_testsuite3_/_testcase9_| 9  Test case return 'Expected_f_a_i_l   for ... tsPro Manual edit please     
EOF
print Fout $str;
close Fout; 

	############ Generate taf Property file for _testsuite3_
open Fout, ">$c/$_TAF/_testsuite4_/tsProperty.txt";
$str = <<EOF;
web_ui_title: Testcase/Testsuite Property Operation Test Suite : web_ui_title
$c/$_TAF/_testsuite4_/testcase0001| 1  Test case 1 add testcase Property1 = propertyValue1                       
$c/$_TAF/_testsuite4_/testcase0002| 2  Test case 2 get testcase Property1 = propertyValue1A                      
$c/$_TAF/_testsuite4_/testcase0003| 3  Test case 3 add testsuite Property                                        
$c/$_TAF/_testsuite4_/testcase0004| 4  Test case 4 get testsutie Property
EOF
print Fout $str;
close Fout; 


	############ Generate taf Property file for webUI tc description
open Fout, ">$c/$_TAF/tsProperty.txt";
print Fout<<EOF;
web_ui_title: Test Automation Framework : web_ui_title
$c/$_TAF/_testsuite1_| 1  TAF Testbed 1  : Test Case Access: TC list, TC execution, TC Reporting
$c/$_TAF/_testsuite2_| 2  TAF Testbed 2  : TAF can have many Testsuites 
$c/$_TAF/_testsuite3_| 3  TAF Testbed 3  : Concurrency, Performance TCs, Logging, list/exec failed TCs
$c/$_TAF/_testsuite4_| 4  TAF Testbed 4  : Test case/suite property operations
$c/$_TAF/_testsuite5_| 5  TAF/pyAnvil/MV Integration
$c/$_TAF/_testsuite6_| 6  TAF MV TC Integration 
EOF
close Fout;




1;
}



sub prDriver {
	my $driver=<<EOF;
use Test::AutomationFramework;
use Getopt::Long;
	GetOptions(
	    'processTSs=s'         	      => \\\$processTSs,			
	    'processTCs|settings|s=s'         => \\\$processTCs,			
	    'processTC|tc=s'                  => \\\$processTC,		
	    'processProperty|property=s'      => \\\$processProperty,		
	    'help'                  	      => \\\$help,	
	);
\$TAF = new Test::AutomationFramework;
if (\$help) 		{\$TAF->help();}
if (\$prDriver) 	{\$TAF->prDriver();}
if (\$processTSs) 	{ \$TAF->processTSs(\$processTSs);}
if (\$processTCs) 	{ \$TAF->processTCs(\$processTCs);}
if (\$processProperty) 	{ \$TAF->processProperty(\$processProperty);}
if (\$processTC) 	{ \$TAF->processTC(\$processTC);}
if (\$scanTestsuites) 	{ \$TAF->scanTestsuites();}
foreach \$each (\@ARGV) {\$cmdLine =\$cmdLine.\$each.';'; } \$TAF->processTCs(\$cmdLine) if \$cmdLine;

EOF
if (@_) { return $driver;} else { print $driver;}
}


################################################################################
#	Subroutine Name : getDate
#		Function: get current Datetime 
#	Input Parameters: 
#	Output/Returns  : currentDate in the format of 2010-10-02 12:11:22
################################################################################
sub getDate ( ) {	# 	TH:Generic Functions: get current Time (TH:Generic Functions)
    my ( $y, $m, $d, $hh, $mm, $ss ) = (localtime)[ 5, 4, 3, 2, 1, 0 ];
    $y += 1900;
    $m++;
    my $iso_sale_time =
      sprintf( "%d-%02d-%02d %02d:%02d:%02d", $y, $m, $d, $hh, $mm, $ss );
    $iso_sale_time;
}

################################################################################
#	Subroutine Name : appendtoFile
#		Function: append text to a file
#	Input Parameters: 1 Filename 2 String
#	Output/Returns  : New File with the appened text
################################################################################
sub appendtoFile() {  	# TH:Generic Functions: append to file (TH:Generic Functions)
    my $fname = $_[0];
    open Fout, ">>$fname";
    print Fout "$_[1]";
    close Fout;
}

################################################################################
#	Subroutine Name : appendtoFileFile
#		Function: append file1 to file2
#	Input Parameters: 1 Filename 2 String
#	Output/Returns  : New File with the appened text
################################################################################
sub appendtoFileFile() {  	# TH:Generic Functions: append file to file (TH:Generic Functions)
    my $fname = $_[0]; my $fnameOUT = $_[1];
    open Fin, "$fname" || die "Can't open $fname:$!";
    while ($_ = <Fin>) {
    	&appendtoFile($fnameOUT, $_) if ($_ !~ /^\s*$/);
    }
    close Fin;
}

sub appendtoFileUniq_ { # fname, fileContent, maxTCExecTime 
    my $fname         = "e.txt"    ; $fname     = shift if @_; 
    my $content         = ""         ; $content     = shift if @_;
    my $MaxTCExecTime     = 10          ; $MaxTCExecTime= shift if @_; 
    my $fname_         = $fname."_"    ;
    my %record;
    while (-e $fname_) { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }

    open Fin ,  "$fname"; while ($_ = <Fin>) { $_ =~ /($_TAF.+)[\/|\\]_tcLog\.html/; $record{$1} = $_; } close Fin;
    $content =~ /($_TAF.+)[\/|\\]_tcLog\.html/; $record{$1} = $content;
    open Fout, ">$fname_"; foreach my $each (sort keys %record) { print Fout $record{$each} } close Fout;
    move ($fname_, $fname);
}

################################################################################
#	Subroutine Name : createFile
#		Function: create a new file
#	Input Parameters: 1 Filename 2 String
#	Output/Returns  : New File with the appened text
################################################################################
sub createFile() {  	# TH:Generic Functions: create to file (TH:Generic Functions)
    my $fname = $_[0];
    $fname =~ s/\\/\//g;
    if (-e &getDir($fname)) {;} else {mkpath &getDir($fname);}
    open Fout, ">$fname";
    print Fout "$_[1]\n";
    close Fout;
}

################################################################################
#	Subroutine Name : readFile
#		Function: Read a file
#	Input Parameters: Filename 
#	Output/Returns  : String
################################################################################
sub readFile() {  	# TH:Generic Functions: read file (TH:Generic Functions)
    my $fname = $_[0];
    if ( -e $fname ) {
    open Fin, "$fname";
    @_ = <Fin>;
    close Fin;
    return "@_";
    } else { return "";}
}


################################## STOP TAF Gracefully  ############################################
sub detectExitTAFGracefullyLock  { if ( -e $exitTAFGracefullyLock) { return "locked"; } else { return "unlocked"; } }
sub setExitTAFGracefullyLock     { open Fout, ">$exitTAFGracefullyLock"; close Fout; }
sub releaseExitTAFGracefullyLock { unlink $exitTAFGracefullyLock; } 
sub exitTAF			 { open Fout, ">$exitTAFGracefullyLock"; close Fout; }
################################## concurrency file log ############################################

sub updateWeb_ {
	my  %tsProperty;
 	my $tcname 		= 'TC_tc1'	; $tcname = shift if @_;	
 	my $scrollamount 	= 0 		; $scrollamount = shift if @_;
	my $borderwidth  	= 0 		; $borderwidth  = shift if @_;
	my $borderstyle  	= 'SOLID' 	; $borderstyle  = shift if @_;
	my $movingString 	= '>' 	 	; $movingString = shift if @_;
	my $MaxTCExecTime	= 10 	 	; $MaxTCExecTime= shift if @_; 
	@_ = split (/,/ , $scrollamount);
	if ($_[0]) { $scrollamount = $_[0];}
	if ($_[1]) { $borderwidth= $_[1];} 
	if ($_[2]) { $borderstyle= $_[2];} 

	if ($movingString =~ /runTC/i) { $movingString = '>'; }
	if ($movingString =~ /runTS/i) { $movingString = '>>'; }

	$tcname = &getTCName($tcname); $tcname =~ s/\\/\//g;
	############ BEGIN #############
	my $fname_ =	$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_"; 
	while (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_") { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml) {
 		open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml;
 		open Fout, ">".$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_";
 		while ($_ = <Fin>) {
 			my $tcnameTmp = $tcname;
 			if ( $_ =~ /$tcnameTmp/i) {
 				$_ =~  />(\S+)<\/marquee>/;  my $movingString_ = $1; 
				if ($movingString_) {;} else { $movingString_ = '>>'; }
 				$_ =~ s/>$movingString_<\/marquee>/>$movingString<\/marquee>/;
 				$_ =~  /scrollamount=\s*(\d+)\s*/;  my $scrollamount_ = $1; if ($scrollamount_) {;} else { $scrollamount_ = 0; }
 				$_ =~ s/scrollamount=\s*$scrollamount_\s*/scrollamount=$scrollamount/;

				$_ =~  /border:RED\s+(\d+)\s*px/;  my $borderwidth_ = $1;  if ($borderwidth_) {;} else { $borderwidth_ = 0; }
 				$_ =~ s/border:RED\s*$borderwidth_\s*px/border:RED ${borderwidth}px/;

				$_ =~  /(border:RED\s+\d+\s*px\s+)(DASHED|SOLID|DOTTED)"/;  my $borderstyle_= $2;  if ($borderstyle_) {;} else { $borderstyle_ = 'SOLID'; }
				$_ =~ s/(border:RED\s+\d+\s*px\s+)$borderstyle_"/${1}${borderstyle}"/ ; 
 			} 
 				print Fout $_;
 		}
 		close Fout;
 		close Fin;
		move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml);
	} ############ END ###############

	############ BEGIN #############
	my $fname_http =	$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_"; 
	while (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_") { my $mtime = ( stat $fname_http)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http) {
 		open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http;
 		open Fout, ">".$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_";
 		while ($_ = <Fin>) {
 			my $tcnameTmp = $tcname;
 			if ( $_ =~ /$tcnameTmp/i) {
 				$_ =~  /scrollamount=\s*(\d+)\s*/;  my $scrollamount_ = $1; if ($scrollamount_) {;} else { $scrollamount_ = 0; }
 				$_ =~ s/scrollamount=\s*$scrollamount_\s*/scrollamount=$scrollamount/;

				$_ =~  /border:RED\s+(\d+)\s*px/;  my $borderwidth_ = $1;  if ($borderwidth_) {;} else { $borderwidth_ = 0; }
 				$_ =~ s/border:RED\s*$borderwidth_\s*px/border:RED ${borderwidth}px/;

				$_ =~  /(border:RED\s+\d+\s*px\s+)(DASHED|SOLID|DOTTED)"/;  my $borderstyle_= $2;  if ($borderstyle_) {;} else { $borderstyle_ = 'SOLID'; }
				$_ =~ s/(border:RED\s+\d+\s*px\s+)$borderstyle_"/${1}${borderstyle}"/ ; 
 			} 
 				print Fout $_;
 		}
 		close Fout;
 		close Fin;

		move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http);
	} ############ END ###############

#	move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml);
	return "tcCtr_Dynamics=$scrollamount";
}

sub mergeFile_ {
 	my $indexFName = "index.htm"		; $indexFName   = shift if @_; 
 	my $reportFName = "_tcReport_.html"	; $reportFName  = shift if @_;
        my $MaxTCExecTime     = 10          	; $MaxTCExecTime= shift if @_; 

	$indexFName =~ s/\//\\/g;
	$reportFName =~ s/\//\\/g;

 	my %index; my $indexFName_ = $indexFName."_"; 
        while (-e $indexFName_) { my $mtime = ( stat $indexFName)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	if ( -e $indexFName)  {open Fin, $indexFName ; while ($_ = <Fin> ) { if ($_ =~ /$_TAF\/(.+)\/_tcLog.html/) { $_ =~ /$_TAF\/(.+)\/_tcLog.html/; $index{$1} = $_; } } close Fin; }
 	if ( -e $reportFName) {open Fin, $reportFName; while ($_ = <Fin> ) { if ($_ =~ /$_TAF\/(.+)\/_tcLog.html/) { $_ =~ /$_TAF\/(.+)\/_tcLog.html/; $index{$1} = $_; } } close Fin; }
}

sub updateWeb1_ {
	my  %tsProperty;
 	my $tcname 		= 'TC_tc1'	; $tcname = shift if @_;	
	my $tcHtml        	= "" 	 	; $tcHtml = shift if @_;
	my $MaxTCExecTime	= 10 	 	; $MaxTCExecTime= shift if @_; 
	my $testsuiteTotalExecTime =  &getTestsuiteTotalExecTime ("$SvrDrive/$SvrProjName/$reportHtml1");

	$tcname = &getTCName($tcname); $tcname =~ s/\\/\//g;
	my $fname_ =	$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_"; 
	while (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_") { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	my $findMatch = 'n';
	if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml) {
 		open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml;
 		open Fout, ">".$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_";
 		while ($_ = <Fin>) {
 			my $tcnameTmp = $tcname;
 			if ( $_ =~ /$tcnameTmp/i) {
				$_ = $tcHtml;
				$findMatch ='y';
 			} 

			# Update Testsuite properties on Test case level
			if ( $_ =~ /\(Avg Time is\s+(\d+:\d+:\d+)\)/) { $_ =~ s/Avg Time is $1/Avg Time is $testsuiteTotalExecTime/; }
 			print Fout $_;
 		}
 		close Fout;
 		close Fin;

		move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml);
	}
	return 1;
}

sub updateWeb1Http_ {
	my  %tsProperty;
 	my $tcname 		= 'TC_tc1'	; $tcname = shift if @_;	
	my $tcHtml        	= "" 	 	; $tcHtml = shift if @_;
	my $MaxTCExecTime	= 10 	 	; $MaxTCExecTime= shift if @_; 
	my $testsuiteTotalExecTime =  &getTestsuiteTotalExecTime ("$SvrDrive/$SvrProjName/$reportHtml1");

	$tcname = &getTCName($tcname); $tcname =~ s/\\/\//g;
	my $fname_ =	$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_"; 
	while (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_") { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	my $findMatch = 'n';
	if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http) {
 		open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http;
 		open Fout, ">".$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_";
 		while ($_ = <Fin>) {
 			my $tcnameTmp = $tcname;
 			if ( $_ =~ /$tcnameTmp/i) {
				$_ = $tcHtml;
				$findMatch ='y';
 			} 

			# Update Testsuite properties on Test case level
			if ( $_ =~ /\(Avg Time is\s+(\d+:\d+:\d+)\)/) { $_ =~ s/Avg Time is $1/Avg Time is $testsuiteTotalExecTime/; }
 			print Fout $_;
 		}
 		close Fout;
 		close Fin;

		move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http);
	}
	return 1;
}
sub getWeb_ {
	my  %tsProperty;
 	my $tcname 		= 'TC_tc1'	; $tcname = shift if @_;	
 	my $scrollamount 	= -1 		; 
 	my $borderwidth  	= -1  		; 
 	my $borderStyle  	= 'SOLID'  	; 
	$tcname = &getTCName($tcname); $tcname =~ s/\\/\//g;

	if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml) {
 		open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml;
 		while ($_ = <Fin>) {
 			my $tcnameTmp = $tcname;
 			if ( $_ =~ /$tcnameTmp/i) {
 				$_ =~  /scrollamount=\s*(\d+)\s*/; $scrollamount = $1;
 				$_ =~  /border:RED\s+(\d+)\s*px/; $borderwidth = $1;
 				$_ =~  /\d+\s*px\s+(\w+)\s*"/; $borderStyle= $1;
 			} 
 		}
 		close Fin;
	}
	return "borderWidth=$borderwidth;scrollAmount=$scrollamount;borderStyle=$borderStyle";
}

sub createFile_ { # fname, fileContent, maxTCExecTime 
	my $fname 		= "e.txt"	; $fname 	= shift if @_; 
	my $content 		= ""	 	; $content 	= shift if @_;
	my $MaxTCExecTime 	= 10 	 	; $MaxTCExecTime= shift if @_; 
	my $fname_ 		= $fname."_"	;
	while (-e $fname_) { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }
	open Fout, ">$fname_" or die $!;
	print Fout $content; 
	close Fout;
	move ($fname_, $fname);
}

sub appendtoFile_ { # fname, fileContent, maxTCExecTime 
	my $fname 		= "e.txt"	; $fname 	= shift if @_; 
	my $content 		= " "	 	; $content 	= shift if @_;
	my $MaxTCExecTime 	= 10 	 	; $MaxTCExecTime= shift if @_; 
	my $fname_ 		= $fname."_"	;
	while (-e $fname_) { my $mtime = ( stat $fname_)[9]; my $current_time = time;  my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; }

	copy ($fname, $fname_);
	open Fout, ">>$fname_" or die $!;
		if ($content) {;} else { $content = "";}
	print Fout $content; 
	close Fout;
	move ($fname_, $fname);
}

sub appendtoFileFile_ {  	# TH:Generic Functions: append file to file (TH:Generic Functions)
    my $fname = $_[0]; my $fnameOUT = $_[1];
    open Fin, "$fname" || die "Can't open $fname:$!";
    my $content;
    while ($_ = <Fin>) {
	    if ($_ !~ /^\s*$/) {$content = $content .$_; } 
    }
    close Fin;
    	&appendtoFile_($fnameOUT, $content) ;
}

################################## concurrency file log ############################################
sub getRoot_4  { my $string = shift; $string =~ s/\w:[\/|\\]//; return $string; }
sub getRoot_3 { my $string = shift; @_ = split /\\|\//, $string; 
	if    ($#_== 1) { return $_[$#_]; }
	elsif ($#_ == 2) { my $tmp = $#_ -1; return $_[$tmp].'/'.$_[$#_]; }
	elsif ($#_ == 3) { my $tmp = $#_ -1; my $tmp1 = $#_ -2;  return $_[$tmp1].'/'.$_[$tmp].'/'.$_[$#_]; }
	elsif ($#_ == 4) { my $tmp = $#_ -1; my $tmp1 = $#_ -2;  my $tmp2 = $#_ - 3; return $_[$tmp2].'/'.$_[$tmp1].'/'.$_[$tmp].'/'.$_[$#_]; }
	elsif ($#_ == 5) { my $tmp = $#_ -1; my $tmp1 = $#_ -2;  my $tmp2 = $#_ - 3; my $tmp3 = $#_ - 4; return $_[$tmp3].'/'.$_[$tmp2].'/'.$_[$tmp1].'/'.$_[$tmp].'/'.$_[$#_]; }
}

sub getRoot { my $string = shift; @_ = split /\\|\//, $string; return $_[$#_]; }
sub getDir  { my $string = shift; my $root =&getRoot($string); $string =~ s/([\\|\/])?$root//i; return $string;  }
sub getRoot_1 { my $string = shift; @_ = split /\\|\//, $string; return $_[$#_-1]; }


sub prHtml1 {		# print index.htm beginnings
	my $tcPropertyPatternPattern_ = ".*"; ####################### Reset the tcPropertyPatternPattern for index.htm
#	&readTestSuitProperty (); 	# Read web_ui_title 
	# my $testsuiteTotalExecTime =  &getTestsuiteTotalExecTime ("$SvrDrive/$SvrProjName/index.htm"); 
	my $testsuiteTotalExecTime =  &getTestsuiteTotalExecTime ("$SvrDrive/$SvrProjName/$reportHtml1"); 
&createFile_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml, '' );
&createFile_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml_http, '' );
my $str =<<EOF;
taf.pl       : TAF Driver    
taf.bat      : TAF testbed setup
tc.pl        : TC hook       
_tcAppend.txt: TC log  hook 
EOF

	my $strTmp = sprintf "%-${webUI_TCDescWidth}s", "                  Testcase Description"; 		
	my $TCCtrToolTip = sprintf "Run Test Suite 24/7 (Avg Time is $testsuiteTotalExecTime)"; 
	my $perl = $^X;  $perl =~ s/\\/\\\\/g;
	my $tmp1 = sprintf("<a href=\"${url}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName SysDrive=$SvrDrive;Execution_24_7=y;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;exec')\" title=\"$TCCtrToolTip\">");
	my $tmp11= sprintf("<a href=\"${url}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName exitTAF')\" title=\"Stop Test Execution gracefully\" >");
	my $tmp2 = sprintf("<a href=\"${url}/$SvrProjName/index_failed.htm\" title=\"Display *Failed* TCs\">");
	my $tmp3 = sprintf("<a href=\"${url}/$SvrProjName/index_passed.htm\" title=\"Display *Passed* TCs\">");
	my $tmp31= sprintf("<a href=\"${url}/$SvrProjName/index_others.htm\" title=\"Display *others* TCs\">/</a>");
	my $tmp4 = sprintf("<a href=\"${urlHttp}/$SvrProjName/index_http.htm\" title=\"Run TAF-Team Version based on IIS/http\"> <font color=\"white\">TC Exec Command</font></a>");
	my $tmp5 = sprintf("<a href=\"${urlHttp}/$SvrProjName/index_http.htm\" title=\"Run TAF-Team Version based on IIS/http\">TC Exec Command</a>");
	my $tmp6 = "<a title=\"Execution time = $testsuiteTotalExecTime (s) \">(sec)</a>";
	my $tmp7 = sprintf("<a href=\"${urlHttp}/$SvrProjName/index_http.htm\" title=\"Run TAF-Team Version based on IIS/http\"> <font color=\"white\">");
	my $tmp8 = sprintf("<a href=\"${url}/index.htm\" title=\"Run TAF-Team Version based on IIS/http\">");
	my $tmp9 = sprintf("<a href=\"${url}/$SvrProjName/$reportHtmlSummary\" title=\"Display TC Summary\">");
	my $tmp9A = sprintf("<a href=\"${url}/$SvrProjName/$reportHtmlSummary\" title=\"Latest TC pass/fail (Gree/Red) Click to Display Test Suite Summary\">");
	my $tmp9B = "Results                                                                                                                              ";
	   $tmp9B = substr ($tmp9B, 0, $passFailDisplayWidth);
	my $tmp10 = sprintf("<a href=\"${url}/$SvrProjName/$reportHtmlSummary\" title=\"$reportHtmlSummaryStr\">");
	my $passFailDisplay = &genPassFailDisplay("");
	
my $tmp =<<EOF;

<html>
<head> 
<META http-equiv="refresh" content="20"> 
		<HTA:APPLICATION ID="oMyApp" 
		    APPLICATIONNAME="Application Executer" 
		    BORDER="no"
		    CAPTION="no"
		    SHOWINTASKBAR="yes"
		    SINGLEINSTANCE="yes"
		    SYSMENU="yes"
		    SCROLL="no"
		    WINDOWSTATE="normal">
	<script language="JavaScript">
		function RunFile(file) {
			// alert("file is " + file );
			WshShell = new ActiveXObject("WScript.Shell");
			WshShell.Run(file, 1, false);
		}

		function RunFileHTTP(testsuite, testcase) {
			// alert("testsuite is " + testsuite + " testcase is " );
			WshShell = new ActiveXObject("WScript.Shell");
		    	cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /delete /tn TAF_'+ testsuite + '_' + testcase + ' /f'; WshShell.Run(cmd, 1, false);
			cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /create /TR "$c\\\\$_TAF\\\\taf.pl testsuit='+testsuite+';testcaseExec='+testcase+';exec" /TN TAF_'+testsuite+'_'+testcase+' /sc monthly /mo 1 /F'; WshShell.Run(cmd, 1, false);
    		  	cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /run /tn TAF_'+testsuite+'_'+testcase; WshShell.Run(cmd, 1, false);
		}
		// <body OnLoad ="function1()">
	</script>
</head>
<script type="text/javascript"> if (navigator.appName != "Microsoft Internet Explorer") alert("Please use IE to access TAF's webUI") </script>
<body>
<pre>
<p>
<h2> ${tmp8}$web_ui_title</a></h2> 
${tmp9A}${tmp9B}</a>${tmp1}Execution</a>  <a title=\"Click Testcase Desc to view TC logs\">$strTmp</a>    ${tmp3}Pass</a>${tmp31}${tmp2}Fail</a>      ${tmp6} <a title=\"pass/fail counts\">      ${tmp7}Exec T</font></a>        <a title=\"Manual command to exec TC\">   ${tmp4}  </span>
EOF

&appendtoFile_ ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml, $tmp);

my $tmp1_http = sprintf("<a href=\"${urlHttp}/$SvrProjName/$reportHtml_http\" onClick=\"RunFile(\'http://$ip/$_TAF/$SvrProjName/ts.hta\')\"  title=\"$TCCtrToolTip\" > "); 
my $tmp2_http = sprintf("<a href=\"${urlHttp}/$SvrProjName/index_http_failed.htm\" title=\"Click to display *Failed* TCs\">"); 
my $tmp3_http = sprintf("<a href=\"${urlHttp}/$SvrProjName/index_http_passed.htm\" title=\"Click to display *Passed* TCs\">");
my $tmp31_http= sprintf("<a href=\"${urlHttp}/$SvrProjName/index_http_others.htm\" title=\"Click to display *Others* TCs\">/</a>");
my $tmp4_http = sprintf("<font color=\"white\">TC Exec Command</font>");
my $tmp6_http = "<a title=\"Execution time = ".  $testsuiteTotalExecTime ."(s) \">(sec)</a>";
my $tmp7_http = sprintf("<a href=\"${urlHttp}/$SvrProjName/index.htm\" title=\"Click to run TAF-PC Version with NO IIS/http\">");
my $tmp_http =<<EOF;

<html>
<head> 
<META http-equiv="refresh" content="20"> 
		<HTA:APPLICATION ID="oMyApp" 
		    APPLICATIONNAME="Application Executer" 
		    BORDER="no"
		    CAPTION="no"
		    SHOWINTASKBAR="yes"
		    SINGLEINSTANCE="yes"
		    SYSMENU="yes"
		    SCROLL="no"
		    WINDOWSTATE="normal">
	<script language="JavaScript">
		function RunFile(file) {
			// alert("file is " + file );
			WshShell = new ActiveXObject("WScript.Shell");
			WshShell.Run(file, 1, false);
		}

		function RunFileHTTP(testsuite, testcase) {
			// alert("testsuite is " + testsuite + " testcase is " );
			WshShell = new ActiveXObject("WScript.Shell");
		    	cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /delete /tn TAF_'+ testsuite + '_' + testcase + ' /f'; WshShell.Run(cmd, 1, false);
			cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /create /TR "$c\\\\$_TAF\\\\taf.pl testsuit='+testsuite+';testcaseExec='+testcase+';exec" /TN TAF_'+testsuite+'_'+testcase+' /sc monthly /mo 1 /F'; WshShell.Run(cmd, 1, false);
    		  	cmd = '$c\\\\windows\\\\system32\\\\schtasks.exe /run /tn TAF_'+testsuite+'_'+testcase; WshShell.Run(cmd, 1, false);
		}
		// <body OnLoad ="function1()">
	</script>
</head>
<script type="text/javascript"> if (navigator.appName != "Microsoft Internet Explorer") alert("Please use IE to access TAF's webUI") </script>
<body>
<pre>
<p>
<h2> $web_ui_title </h2>
<a title=\"latest Test Result pass/fail = Green/Red\">L</a>            <a title=\"Click Testcase Descriptoin to view logs \">$strTmp</a>          -${tmp3_http}Pass</a>${tmp31_http}${tmp2_http}Fail</a>-  <a title=\"pass/fail counts\">${tmp1_http}Counters</a>  Exec T $tmp6_http     <a title=\"Manual command to exec TC\">     ${tmp4_http} </a> </span>
EOF


&appendtoFile_ ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml_http, $tmp_http);
}

sub prHtml2 {	# print index.htm endings
my $tmp =<<EOF;
</pre></body>
</html>
<style type="text/css"> a { text-decoration:none} </style> 
EOF
 &appendtoFile_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml, $tmp );
 &appendtoFile_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml_http, $tmp );
}



__END__
		TAF Function Summary  (Code Name: th.pl as of Sept 27, 2010)
------------------------------------------------------------------------------------------
TH Function Category     Function Name            Function Description
------------------------------------------------------------------------------------------
TH:TC Managements        logIsValid               Verify if a log is valid by comparing TC created T and log create T Commented Done 
TH:TC Managements        tcRunningYN              get the TC result Pass/Fail                                         Commented Done
TH:TC Managements        getProperty              get TC Property Names                                               Commented Done
TH:TC Managements        getPropertyValues        get TC Property Values                                              Commented Done
TH:TC Managements        deleteProperty           delete TC Property                                                  Commented Done
TH:TC Managements        addProperty              add TC Property                                                     Commented Done
TH:TC Managements        modifyProperty           modify TC Property                                                  Commented Done
TH:TC Managements        appendPropFile           append to TC Property File                                          Commented Done
TH:TC Managements        createPropFile           create TC Property File                                             Commented n/a
TH:TC Managements        readProperty             Read TC Property                                                    Commented n/a
TH:TC Managements        updateTCResultProperty   Update TC Property                                                  Commented n/a
TH:TC Managements        genTC                    Generate a HelloWorld TC                                            Commented Done

TH:TC Report             Report                   TC Report Function                                                  Commented Done
TH:TC Report             reportUpdateOnWeb        update TC Report on webUI                                           Commented 
TH:TC Report             logExist                 Determine if a log exists                                           Commented Done

TH:TC Execution          ReportAvgResponseTime    report TC Average Response Time                                     Commented n/a
TH:TC Execution          lastPassFail             get the latest TC Pass/Fail Result                                  Commented Done
TH:TC Execution          longivityPeriod          If the TC in LongivityPeriod                                        Commented 

TH:WebUI                 thWebUIUpdate            Update the webUI based on thProperty.txt                            Commented v2
TH:WebUI                 tcStatusHtmlSync         synchrinize the HTML with with TC Result                            Commented v2
TH:WebUI                 tcStatusHtml             Display the TCStatuse in Html format                                Commented v2
TH:WebUI                 rearrangeWebUI           Update webUI based on thProperty.txt                                Commented v2
TH:WebUI                 tcLog2Web                Update TC Log on webUI                                              Commented v2

TH:Concurrency Control   tcRunningYNOther         get the running TC Status for Concurrency Control.                  Commented v2          
TH:Concurrency Control   tcScheduledYNOther       get the scheduled TC for Concurrency Control.                       Commented v2
TH:Concurrency Control   tcQueue                  TC Queue function for Concurrency Control.                          Commented v2
TH:Concurrency Control   tcDeQueue                TC deQueue for Concurrency Control                                  Commented v2

TH:Email Notification    emailNotification        Process the Outlook email Notification Commands                     Commented v3  
TH:Conti. Integration    thBuzRule                Handle Continuous Integration                                       Commented v3

TH:Assist Functions      genTimeStr               time format function                         			      Commented	                                   
TH:Assist Functions      getIP                    TH:Generic Functions: get IP of local machine                       Commented 
TH:Assist Functions      genThProperty            generate TH property file                                           Commented  
TH:Assist Functions      printLibraryFun          print QTP Library Functions                                         Commented 
TH:Assist Functions      readTestHarnessCmdLine   read Test Harness Cmd Line args                                     Commented 
TH:Assist Functions      genQTPInputs             generate QTP Input files                                            Commented 
TH:Assist Functions      thPropertyUpdate         update TH property                                                  Commented 
TH:Assist Functions      prHelp_short             Print the short Help                                                Commented todo
TH:Assist Functions      prHelp                   print lengthy Help                                                  Commented 
TH:Assist Functions      genQTPDriver             Generic qtpDriver                                                   Commented 
TH:Assist Functions      genQTPLibrary            Generate QTP Library                                                Commented 
TH:Assist Functions      genCmd                   Generate the Test Harness ASP files                                 Commented 

TH:Generic Functions     appendtoFile             TH:Generic Functions: append to file                                Commented Done
TH:Generic Functions     createFile               TH:Generic Functions: create a file                                 Commented Done
TH:Generic Functions     getDate                  TH:Generic Functions: get current Time                              Commented Done
TH:Generic Functions     reverse                  TH:Generic Functions: reverse a Associate Array                     Commented            
TH:Generic Functions     strLen                   Generic Functon: return Str len                                     Commented            
TH:Generic Functions     decrCtr                  Decrease Ctr                                                        Commented            
TH:Generic Functions     incrCtr                  Increase Ctr                                                        Commented            
TH:Generic Functions     getCtr                   Get Ctr                                                             Commented 
TH:Generic Functions     getCurrentTime           TH:Generic Functions: getCurrentTime                                Commented 
TH:Generic Functions     getHost                  getHost function done by SZ Team Charlie and David                  Commented 
TH:Generic Functions     getHostFromIP            Get Host done by SZ Team Charlie and David                          Commented               

------------------------------------------------------------------------------------------


=head1 NAME
Test::AutomationFramework - Test Automation Framework  (TAF)

=head2 SYNOPSIS
	1. Download and install Test::AutomationFramework from CPAN
	2. DOS>perl -MTest::AutomationFramework -e "help"
	3. A WebUI is created, which can display and execute, as well as view test case by *ONE* mouse click
	3. Modify taf.bat for the automated test suit structures 
	4. Modify c:\[test_suit]\[test_case]\tc.pl to plug-in the customer test case
	5. Execute taf.bat to get the webUI
	6. Run test cases, view test result, view test logs with mouse click only. - Enjoy TAF
	7. Please email ywangperl@gmail for questions/suggestions/bugs 

=head2 DESCRIPTION
	TAF manages automated test cases regarding test setup, test query, test execution and 
	test reult reportings without any programming nor reading user manual. 

	TAF defines a automated test case as [c:]\[test_suite]\[test_case]\tc.pl
		tc.pl returns Pass|fail|numerical number
		tc.pl creates tc's log file as [c:]\[test_suite]\[test_case]\tc.pl
		tc.pl creates test suite's webUI at [c:]\[test_suite]\index.htm 

=head1  LICENSE
	This script is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

=head1 AUTHOR
    	Yong Wang (ywangperl@gmail.com)

=cut;


1;

use Test::AutomationFramework; $TAF = new Test::AutomationFramework;
foreach $each (@ARGV) { $cmdLine =$cmdLine.$each.';'; } $TAF->processTCs($cmdLine);

rem taf.pl -s ts=_test_suit1_;tcop=list rem ts can't be regExp
rem taf.pl -s ts=_test_suit1_;tn=*1*;tcop=list rem ts can't be regExp
rem
rem taf.pl -s ts=_test_suit1_;tcop=exec rem ts can't be regExp
rem taf.pl -s ts=_test_suit1_;tn=*1*;tcop=list rem ts can't be regExp
rem taf.pl -s printVars	
rem tas.pl help;printVars;ts=_test_suit3_;tcop=list;list
rem tas.pl help;printVars;ts=_test_suit3_;tcop=list;exec

rem taf.pl help;printVars;ts=_test_suit3_;tcop=list;list=regExq  TODO
rem taf.pl help;printVars;ts=_test_suit3_;tcop=list;exec=regExq  TODO
todo: hardcoded c: 
taf.pl listAll
taf.pl ts=_test_suit1_ -listTC
taf.pl ts=_test_suit1_ tc=*test* -listT
rem taf.pl listAll=test_suit1;exec
rem taf.pl listAll=test_suit1;list


taf.pl 'testsuit=_default_testsuite_;create=testcase01/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_1:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase02/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_2:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase03/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_3:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase04/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_4:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase05/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_5:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase06/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_6:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase07/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_7:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase08/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_8:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase09/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_9:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase10/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_10:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase11/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_11:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase12/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_12:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase13/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_13:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase14/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_14:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase15/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_15:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase16/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_16:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase17/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_17:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase18/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_18:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase19/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_19:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase20/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_20:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase21/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_21:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase22/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_22:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase23/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_23:customTC'
taf.pl 'testsuit=_default_testsuite_;create=testcase23/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_23:customTC'

taf.pl testsuit=propertyChangedEvent;list
rem taf.pl testsuit=propertyChangedEvent;exec
rem taf.pl testsuit=propertyChangedEvent;updateWeb=_testcase2_/1

-- history --

* using the directory recursive for searching testcases
* CustomTC:....:CustomTC

__END__

############################ index_pyAnvil.pl ###################################
use strict;
&execTC($ARGV[0]);

sub execTC {
	my $passFail='FAIL'; my $logHtml; my $logXml	;
	my $pyAnvil= 'c:/pyAnvil/pyAnvil -s '		;
	my $tcDir  = "c:/test_pyAnvil/"			;
	my $testsuiteHook = "index.pl"			; 
	       
	my $tcId   = -1					; $tcId   = shift if @_;
	my $tcDesc = "Testcase $tcId Demo"		; $tcDesc = shift if @_;
	my $tsDesc = "pyAnvil Testsuite Demo"		; $tsDesc = shift if @_; 

	$testsuiteHook = $tcDir.$testsuiteHook		; 
	my $tcScenario = "_tc.xml"			; $tcScenario = $tcDir."_tc.xml"	; 
	my $tcLog_pyAnvil = "_tcLogAppend_.txt"         ; $tcLog_pyAnvil = $tcDir."$tcLog_pyAnvil";
	if ($tcId =~ /^\s*$/) { print `$testsuiteHook`; return 0; }

my $str=<<EOF;
<?xml version="1.0" encoding="utf-8"?>
<XMLTestCollection>
    <TestList TestCases="$tcDesc">
	<ToolCase>
	    <Name>$tcDesc</Name>
	    <Executable>C:/strawberry/perl/bin/perl.exe</Executable>
	    <Parameters>$testsuiteHook $tcId</Parameters>
	    <StdoutContains>PASS</StdoutContains>
	</ToolCase>
    </TestList>
</XMLTestCollection>
EOF

	open Fout, ">$tcScenario"; print Fout $str; close Fout; my $cmd = $pyAnvil."$tcScenario"; my $rst = `$cmd`; 

	foreach my $each (split /\n/, $rst) { 
		if (  $each =~ /^\s+PASS\s+/) { $passFail = "PASS";}
		elsif ($each =~ /^\s+FAIL\s+/) { $passFail = "FAIL";}
		elsif ($each =~ /^\s+XML:\s+(.+)/) { $logXml = $1;}
		elsif ($each =~ /^\s+HTML:\s+(.+)/) { $logHtml = $1;}
	}

open Fout, "> $tcLog_pyAnvil "; print Fout "$rst\n"; close Fout;  print "- > $tcLog_pyAnvil\n"; 
	print "$passFail\n"; 
}
############################ index_pyAnvil.pl ###################################

##################### index.pl for pyAnvil ############################
my $testsuiteHook = "powershell -executionpolicy unrestricted -file c:/test_pyAnvil/index.ps1 $ps1_args";


if    ($ARGV[1]) { print &call_index($ARGV[0], "noExec") ;	}  
elsif ($ARGV[0]) { print &call_index($ARGV[0], "yesExec");      }
else             { print &call_index();                         }


sub call_index { 		my $return ; my $recordCtr=1;
	if (@_) {;} else {; return `$testsuiteHook`;}
	my $indexCtr = 9999	; $indexCtr = shift if @_; 		 
	my $execYN   = 'noExec' ; $execYN   = shift if @_; 
	@_ = (split /\n/, `$testsuiteHook`) ;

	foreach $each (@_) { 
		if (($each) && ($each =~ /^\s*_/)) { $return = $return .$each."\n";
		} elsif (($each) && ($each !~ /^\s*_/)) {
			$return = $return . sprintf "TC [%04s] %s\n",$recordCtr,$each; 
			if (($recordCtr == $indexCtr ) && ( $execYN =~ /noExec/i )) { return "TC [$recordCtr]       $each"; } 
			if (($recordCtr == $indexCtr ) && ( $execYN =~ /yesExec/i)) { return `$testsuiteHook $indexCtr `  ; } 
			$recordCtr++;
	  	} 
 	} 
	if ($return =~ /pass/i) { return 0;} 
	if ($return =~ /fail/i) { return 1;} 
}

##################### index.pl for pyAnvil ############################
# * add automated TCS for the new functions to the taf.bat 
# * convert \\ to / for unix port 

############# todo: TAF_Team function ###############
# * Web Service architecture / CGI / RPC
# local run version and /o IIS , support multiple TC Concurrency Control, 
# Working with new Concurrency Control scheme, TCExecSummary, tcDelay=10
# * Linux porting
# * Browser independency 
# * multi-TS Execution sequentially or concurrently

############# todo: TestSuite Machine independency ######
# *  Move/Merge TAF over machine
# ** Merge test suite from one machine
# ** Merge test suite from multi-machine
# ** Move TS from one dir to different dir and regenerate the index*.*
# 0. Move the TS to c:\_MachineName\....
# 1. generateAyAnvilTestsuite.pl
# 2. Copy c:\_TAF\* to new server
# 3. taf testsuite=...;list
# 4. Need to copy the AUT to new server
# 5. use tsProperty.txt to update 
# 6. TS titleName
# 7. TC directory 
#Note: ts;list will update all index.html
###############################################

############# MISC ############################
# * Animate Testsuite bulletin. - generateRootIndex ? 
# * run multi-Testsuites
# * GeneratePShellTS 
# * integrate gerneatePShellTestsuite, 
# * Notif for the expected failure
# * handle unexpected reboot scenario
# * win8 installation
###############################################

############# todo: MarkTC related Actions #########
# * mark by time
# * mark with comments (mouse over comments)
# * history mark link to logs/passfail
# * mark non-executed TCs

#################### Completed Requirements/Bug fixes ###########################
# * passFailDisplayWidth is self-adjustable (see todo) 	-done
# * line 1951: **recursive calling** -Done on 09/04/2012-done
# * 24 exec,  					done	-done
# * Number of TS execution  setGlobal(NofExecution = 5) -done
# * start/stop gracefully	taf.pl exitTAF		-done
# * 24 continuously, in stead of one test suite 	-done
# * Stop TAF graceffully from webUI 			-done
# * bug: * history is incorrect 			-done
# * Bug 'mark' is counted as a failure 			-done
# * Cleanup the directory with index.ps1 		-done (.ps1 takes high priority over *.pl)
# * Bug 'L' has characters other than '*' 		-Ignore (invalid bug)
# * Performance improvements				-done (performanceMode)
# * generateTestsuite will add the tcDesc property 	-done 
# * propertyOperation by propertyOp=add=prop1:val1 	-done 
# * propertyOperation by propertyOp=get_prop1:val1	-done 
# * PropertyFilter for TC operation (e.gl tcDesc = ..)	-done
# * Search by TCDesc					-done by tcProperty
# * list should list all TS/TCs				-done -handle by scanTestsuites
# * Refresh or the historical "*"			-done
# * testcase=testcase[1,2,3..] work for list. not work for exec -done (it works)
# * Bug: pass/fail html is incorrect			-done
###################################################################################
############# done : property operations ###############
# * Add 				-done
# * Delete				-done add=prop:null
# * Modify				-done add=prop:newValue
# * List|get				
############ repalced by [set|get]_tcFilter 
