The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
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::Copy::Recursive qw(fcopy rcopy dircopy fmove rmove dirmove);
use File::Find;
use Regexp::Assemble;
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
genDriver_taf_pl
initTAF
);


our $VERSION = '0.058.36';   	

###################### TAF Global Variables ###############################
	my %tsProperty;my %tafProperty; my %tafPropertyRev; my $propertyOp='';	my $regression=0; my $help=0; my $sleep4Display = 1; my $notUsegetTCName= 0; my %recordTags=();
	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=".*";
	my $exitTAFTCId		;
	my $tcComment1		="Comment1";
	my $tcComment2		="Comment2";
	my $MaxTCExecTime 	= 10	; 
	my $propertyExecCtr	= 0	;
	my $tags		="_full_,_smoke_,_smoketest_,_regression_,_regressiontest_,_bat_,_local_video_,_MVSDK_,_32bit_,_64bit_";

###################### TAF Generated Variables ###############################
	my $scriptName 			= $0; $scriptName =~ s/\\/\\\\/g; 
	my $workingDir			= getcwd(); 
	my $TSHookName 			= "index.pl";
	my $TSHookNameGenerated 	= "index.pl";

###################### TAF Default Variables ###############################
	my $interact 			= "n";
	my $tcPropertyPatternName 	= "tcRunResult";
	my $tcPropertyPatternPattern 	= ".*"; 
	my $tcPropertyPatternName1 	= "tcRunResult";
	my $tcPropertyPatternPattern1 	= ".*"; 
	my $tcPropertyPatternName2 	= "tcRunResult";
	my $tcPropertyPatternPattern2 	= ".*"; 
	my $tcPropertyPatternName3 	= "tcRunResult";
	my $tcPropertyPatternPattern3	= ".*"; 
	my $tcPropertyName 		= "all";
	my $tcPropertyPattern		= Regexp::Assemble->new; 
	my $tcNamePattern		= "TC*"; 		
	my $tcOp			= 'list';	
	my $tcCtr  			= 0;
	my $tcDelta			= 20;	
	my $markSymbol			= '|';
	my $c				= "c:";
	my $taf				= "taf.pl";
	my $SUTSymbol			= "_";
	my $tsFilterDefault 		= "_";
	my $tcFilterDefault 		= ".*";
	my $_TAF			= "_TAF";
	my $SvrDrive 			= $c.'/'.$_TAF; 
	my $SvrProjName 		= '_testsuite1_'; 
	my $SvrTCName 			= '_testcase1_';
	my $SvrTCNamePattern 		= "*"; 
	my $SvrPropNamePattern 		= '.*';
	my $SvrPropValuePattern 	= ".*";
	my $SvrTCNameExecPattern 	= ".".$SvrTCNamePattern;
	my $SvrLogDir 			= ''.$SvrProjName.'';
	my $ps1_args 			= "-ps1_args___powershell_args";  	# should not include -ps1_args 
	my $exitTAFGracefullyLock   	= $c.'/'.$_TAF.'/'."_exitTAFGracefully_.txt";
	my $exitTAFGracefullyString	= 1;
 	my $performanceMode		= "slow4webUI"; # fast4cmd
	my $generateTestsuiteBAT	= $c.'/'.$_TAF."/taf_generateTestsuite.bat";
	my $tsFrom			="";
	my $tsTo   			="";
	my $resetTSFileName		="";
	my $externalLogName		="c:/_TAF/externalLog.txt";
	my $commandLogName		="c:/_TAF/_cmdLogs.txt";
	my $commandLogLifeSpan		= "-3 days";
###################### TAF WebUI Default Settings ###############################

	my $excelReportColumnWidth = 9; 
	my $AutomationtsName		="Automation_MVSDK";
 	my $makeMark			= 'n'; my $makeMarkComment		= '';
 	my $makeMarkLastDay		= &getExecDay();
	my $web_ui_title		="Test Automation Framework"; 
	my $webUI_TCDescWidth 		= 80; 
	my $scrollAmount		= 0; 
	my $borderWidth			= 0; 
	my $borderStyle			= "SOLID"; 
	my $passFailDisplayWidth	= 8; 
	my $maxPassFailDisplayWidth	= 40; 
	my $reportHtmlSummaryScale 	= 3600; 				# in seconds
	my $reportHtmlSummaryScaleMajor = 12; 					# in seconds
	my $tsProperty    		= 'tsProperty.txt';
	my $tsPropertyWidth		= 120;
	my $testcaseNode		= "testcase"	; # ".*";					# or .* for testcase
	my $testType    		= "ts";					# ts for testsuite
	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 {			###### Testsuite Loop #####
	if (-e "$c/$_TAF/_tafGlobalVars.txt") { &readTAFGlobalVars(); } else { &printTAFGlobalVars();}  # Global Variables 
	my $returnValue;
	while ((($Execution_24_7 eq 'y') || ($NofExecution > $NofExecutionCtr)) && ($propertyExecCtr == 0)) {
		&markDaily();
		$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_(); $propertyExecCtr++;} # TC Property Process
	#### uncomment for debugging if ($pr2Screen==1) { if ($propertyOp) { print " -> $SvrDrive/$SvrProjName/_${propertyOp}.txt\n"; }	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,"")				;
	# &releaseExitTAFGracefullyLock(); 
	########################################################
}

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\/$testcaseNode/i) && ($File::Find::name =~ /$SvrTCNamePattern/i))  # TC Filter
	{	
		$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;}

		if (    ($tcOp !~ /^\s*$/)&&($SvrTCName =~/$SvrTCNameExecPattern/)&&($tcIdCtr >= $tcIdMin) 
			&& (&getProperties(&getTCName($SvrTCName) , $tcPropertyPatternName, "value") =~ /$tcPropertyPatternPattern/i)
			&& (&getProperties(&getTCName($SvrTCName) , $tcPropertyPatternName1, "value") =~ /$tcPropertyPatternPattern1/i)
			&& (&getProperties(&getTCName($SvrTCName) , $tcPropertyPatternName2, "value") =~ /$tcPropertyPatternPattern2/i)
			&& (&getProperties(&getTCName($SvrTCName) , $tcPropertyPatternName3, "value") =~ /$tcPropertyPatternPattern3/i)
		)  { 		# Property/testcaseExec Filter
		   if ($propertyOp) {								# Property Processor
		        ##################### Property OPeration Start ####################
			if ($propertyOp =~ /tcDescAuto/) {					# add tcDesc when generateTestsuite
				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) || ($propertyOp =~ /^\s*_?list_/i)) {   	# property Operation (_doit_)
				my $propertyOp_  = $propertyOp; 
				$propertyOp_  =~ s/_doit_//g; 
				my $rst = &processProperty("",&getTCName($File::Find::name), $propertyOp_);
				my $File_Find_name = $File::Find::name; $File_Find_name =~ s/\/$tc_pl//g;
				if ($rst =~ /\n/) {
					#### uncomment for debug   print "$File_Find_name\t$propertyOp_=\n$rst\n";
 					&appendtoFile_	($SvrDrive.'\\'.$SvrProjName.'\\'."_$propertyOp_.txt","$File_Find_name\t$propertyOp_=\n$rst\n")				;
					print $SvrDrive.'/'.$SvrProjName.": $propertyOp_ = $rst"				;
				} else {
					#### uncomment for debug   print "$File_Find_name\t$propertyOp_=$rst\n";
 					&appendtoFile_	($SvrDrive.'\\'.$SvrProjName.'\\'."_$propertyOp_.txt","$File_Find_name\t$propertyOp_=$rst\n")				;
					print $SvrDrive.'/'.$SvrProjName.": $propertyOp_ = $rst"				;
				}
			} 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
				my $scrollAmount_ = 1 ; if ($tcOp =~ /list/) { $scrollAmount_ = 0; } 
				if ($tcOp =~ /exec/i) { &updateWeb_(&getDir($File::Find::name),$scrollAmount_, $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 ######################
			if ((&getExitTAFGracefullyLock() eq &getRoot_2($File::Find::name)) || (&getExitTAFGracefullyLock() eq "exitTAF" ) ) { print "TAF exited gracefully\n"; &tcPost(); &releaseExitTAFGracefullyLock(); exit; } 
				&generateRootIndex      ()	; 
		   } 
		} else {	# to handle no-run execution add to ts/tc/thProperty.txt
				&dumyTC_ ();
		}

		$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()	;
	$AutomationtsName   = "$SvrProjName";
    	&generateExcelReport	() 	;	
	&sortCmdLog();
	########################################################
} 

sub markDaily {
	if ((($makeMarkLastDay  < &getExecDay()) && ($makeMark =~ /n/)) or (($tcCtr)%($tcDelta)== 0)) {
		$makeMarkLastDay = &getExecDay(); $makeMark = 'y'; 
	} else {
			$makeMark = 'n';
	}
	$tcCtr++;
}

sub getExecDay {
	my $initStartTime = &UnixDate( "Jan 1, 2012", "%m/%d/%Y %H:%M:%S %Z" );
	my $endStartTime  = &UnixDate( "now" , "%m/%d/%Y %H:%M:%S %Z" );
	my $totalTimeSpan = &DateCalc(&ParseDate($initStartTime),&ParseDate($endStartTime));  #### => YY:MM:WK:DD:HH:MM:SS  the years, months, etc. between the two
	my ($Y,$M,$W,$D,$H,$MIN,$S) = split /:/, $totalTimeSpan;
	my $makeMarkLastDay_Local =  int ($H/24); 
	return $makeMarkLastDay_Local;
}

sub printTAFGlobalVars {
	open Fout, ">$c/$_TAF/_tafGlobalVars.txt";
	#print Fout &getGlobalVars(); 
	print Fout &printGlobalVars(); 
	close Fout;
	print " -> $c/$_TAF/_tafGlobalVars.txt\n";
}

####################### remove duplicate records in file
sub removeDuplicate { 
	my $fname  = shift;
	if ($fname ) {;} else { print "remvoeDuplicate: needs filename\n"; exit; }
	if (-e $fname ) {;} else { print "remvoeDuplicate: $fname doesn't exist\n"; exit; }
	my $fname_tmp = $fname."_.htm"; 
open FILE , $fname; 
open FILE_tmp , "> $fname_tmp";
my $firstOccurence = "_firstOccurence_";
while ($_ = <FILE>) { if (($firstOccurence !~ /^_firstOccurence_$/) and ($_ ne $firstOccurence)) { print FILE_tmp $_; $firstOccurence = $_; } }
close FILE;
close FILE_tmp;
copy ($fname_tmp, $fname);
}

####################### copy Testsuite                  
sub copyTestsuite { shift; print "copy $tsFrom -> $tsTo\n"; rcopy ($tsFrom, $tsTo) or die $!; 1;}
sub copyTS        { shift; print "copy $tsFrom -> $tsTo\n"; 
	if (-e $tsFrom) {;} else { print "Warning: $tsFrom doesn't exist. It is created.\n"; mkdir $tsFrom; }	
	if (-e $tsTo  ) {;} else { print "Warning: $tsTo   doesn't exist. It is created.\n"; mkdir $tsTo  ; }	
	rcopy ($tsFrom, $tsTo) or die $!; return 1;}
############
#

sub generatePropertyTestsuite {goto &generateTestsuiteByDesc}
sub generateTestsuiteBasedOnProperty{
$SvrProjName =~ s/\\/\//g;
&tcMain_1(); 
1;
}
#######################generate Property TCs from desc

sub generateTestsuiteByDesc {
$SvrProjName =~ s/\\/\//g;
&tcMain_1(); 
1;
}
sub tcMain_1 { 
	print "	Scanning for testsuites at $SvrProjName ......\n"; 	
	find(\&recursiveSearchtcMain_1, $SvrProjName); print "	[fyi: -> $generateTestsuiteBAT]\n"; 
1;
}
sub recursiveSearchtcMain_1() { 
	if (($File::Find::name =~ /\/$TSHookName\s*$/) && ($tcPropertyName !~ /all/i))
	{ 	
		&readTCDesc($File::Find::name);
	 	$tcPropertyPattern->add($tcPropertyName ); 
		&generateTS ($File::Find::name, $tcPropertyName); 
	}
}

sub generateTestsuiteScript {
	my $testsuite; # ="c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_pl"; 
	$testsuite = $SvrProjName; my $testsuiteTAF = $SvrProjName; $testsuiteTAF =~ s/c://g; # here
	foreach my $each (split /,/, $tags) {
print <<EOF;
REM c:/_TAF/taf.pl -processTSs create=$testsuite							rem create Tag     TS
c:/_TAF/taf.pl tcPropertyName=$each;testsuite=$testsuite;generateTestsuiteByDesc			rem create Tag     TS
c:/_TAF/taf.pl testsuite=$testsuite/$each;generateTestsuite						rem create TAF-tag TS
c:/_TAF/taf.pl testsuite=$testsuite;testcaseNode=testcase;generateTestsuite				rem create TAF     TS
c:/_TAF/taf.pl testsuite=$testsuiteTAF;testcaseNode=testcase;list

EOF
;
}

}
sub generateTS {
	my $str; 
	my $tsHook 		= "index.pl"	; $tsHook 		= shift if @_			;  
	my $tcPropertyNameLocal = "_smoketest_"	; $tcPropertyNameLocal 	= shift if @_			;
	my $tsDir 		= $tsHook	; $tsDir		=~ s/(\/$TSHookName\s*$)//g	;  
	my $tsHookChild 	= "$tsDir/${tcPropertyName}/$TSHookNameGenerated";
	my $tsDirChild 		= "$tsDir/$tcPropertyNameLocal";

	my $otherCmd = "copy (\"$tsDir/_tcLogAppend.txt\", \"$tsDirChild/_tcLogAppend.txt\")";
	$ps1_args =~ s/\\/\//g;
	if ($tsHook =~ /\.ps1\s*$/)	{ $tsHook	= "powershell -executionpolicy unrestricted -file $tsHook -ps1_args $ps1_args"; } # change1

my $perlCode=<<EOF_;
use File::Copy;
if (\$ARGV[0]) { 
	#_cmd_holder_#
} else {
print \<\<EOF;
#_desc_holder_#
EOF
;
}
EOF_
;
	my $ctr_local=1; 
	for (my $i = 1; $i <= $#tcDesc; $i++) { 
		if ( $tcDesc[$i] =~ /($tcPropertyPattern)/i ) {		
			my $tmp = sprintf ("$tsDir\/testcase%04d => $tsDirChild/testcase%04d", $i, $ctr_local);
			&appendtoFileUniqly("$tsDir/_tcMap.txt", $tmp);
			$ctr_local++;
		}
	}

	$ctr_local=1;
	for (my $i = 1; $i <= $#tcDesc; $i++) { 
		if ( $tcDesc[$i] =~ /($tcPropertyPattern)/i ) {		
		$tcDesc[$i] =~ s/_(\S+)*_//g; 		# remove the tags
		my $tmpStr = "if (\$ARGV[0] == $ctr_local) { \$rst = \`$tsHook $ctr_local -ps1_args $ps1_args\` ; $otherCmd; print \$rst; } \n";	  # change 2

		$perlCode =~ s/#_cmd_holder_#/$tmpStr\t#_cmd_holder_#/;
		# $tmpStr = "$ctr_local. $tcDesc[$i]\n";	# add tcDesc Serial Number
		$tmpStr = "$tcDesc[$i]\n";			# remove tcDesc Serial Number
		$tmpStr =~ s/\\/\//g;  
		$perlCode =~ s/#_desc_holder_#/$tmpStr#_desc_holder_#/;		$ctr_local++;
		}
	}
	if ($ctr_local > 1) {
	if (-e $tsDirChild) {;} else { mkpath $tsDirChild;}
	$perlCode =~ s/#_cmd_holder_#//g;
	$perlCode =~ s/#_desc_holder_#//g;
	open Fout , ">$tsHookChild"; print Fout $perlCode; close Fout; print  "	->$tsHookChild\n";
	}
}

sub readTCDesc {
	my $cmd = shift; my $ctr = 1;
	$#tcDesc = -1;		
	if ($cmd =~ /\.ps1\s*$/) { $cmd = "powershell -executionpolicy unrestricted -file $cmd -ps1_args $ps1_args"; } 		# change 3
 	foreach my $each (split /\n/, `$cmd`) {
 		if ($each =~ /^\s*$/) {; }
 		elsif ($each =~ /^\s*_test/) { ; } 
 		else {
			#### $tcDesc[$ctr++] = $each;
 			$tcDesc[$ctr++] = $each."_full_";
 		}
 	}

}


#######################generate Property TCs from desc
sub scanTestsuites {					######### generate index.htm
	shift; my $doit="n";  my @dir;
	if ($tsFilter =~/_doit_/i) { $doit='y'; $tsFilter =~ s/_doit_//i;} 
	elsif ($tsFilterDefault =~/_doit_/i) { $doit='y'; $tsFilterDefault =~ s/_doit_//i;} 
	elsif ($SvrProjName =~ /_doit_/i) { $doit = 'y'; $SvrProjName =~ s/_doit_//i; }
	
	if ($tsFilterDefault =~ /^$c/)	 {
	@dir = glob "${tsFilterDefault}*"; 
	} else {
	@dir = glob "${c}\\${tsFilterDefault}*"; 	# c:\_filter is added to the search pattern
	}

 	if ($SvrProjName !~ /_testSuit_/i) {
 		if ($SvrProjName =~ /^$c/)	 {
 		@dir = glob "${SvrProjName}*"; 
 		} else {
 		@dir = glob "${c}\\${SvrProjName}*"; 
 		}
 	}

foreach my $each (@dir) {
	$each =~ s/\\/\//g;
find(sub { if (($File::Find::name =~ /index\.\w+$/i) && ($File::Find::name !~ /${c}\/${_TAF}/i)&&($File::Find::name !~ /${c}\\${_TAF}/i)) 
		{
			my $dirName =  $File::Find::name; $dirName =~ s/[\\|\/]index..+$//g; $tsFilterDefault =~ s/\\/\//g;
			if ($dirName =~ /$tsFilterDefault/i) {
			$ps1_args =~ s/ /___/g; 
			$notUsegetTCName = 0; 
			my $cmd = sprintf "$SvrDrive/$taf testsuite=$dirName;web_ui_title=$dirName;ps1_args=$ps1_args;generateTestsuite" ;  
			print "$cmd\n"; 
			if ($doit =~ /\by\b/) { $cmd =~ s/\//\\/g; 
				print "Running ... >>>>\n$cmd\n<<<<\n"; 
				$workingDir = $dirName; $SvrProjName = $dirName; $web_ui_title = $dirName; $ps1_args = $ps1_args; &generateTestsuite();
			}
			}
		}
	 }, $each);
}
	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 getTSMaxScrollAmount{
	my $testsuite= "c:/_TAF/_testsuite2_"; $testsuite = shift if @_;
	my $scrollAmount = -1; 

		if (-e "$testsuite/$reportHtml") {
		open Fin, "$testsuite/$reportHtml";
 		while ($_ = <Fin>) {
			if ($_ =~  /scrollamount=\s*(\d+)\s*/) {
				my $scrollamount = $1; 
				if ($scrollamount > $scrollAmount) { $scrollAmount = $scrollamount; }
 			}
		}
 		close Fin;
	}
	return $scrollAmount;
}

#######################generateRootIndex {
sub generateRootIndex {					######### generate index.htm
	my %tafUI;
	&readTAFProperty(); # read %tafProperty;
	#### part 1 ####
open INDEX, ">$SvrDrive/index.htm_"; 
print INDEX<<EOF;
<html>
<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>
<body><pre>
<h2> <a href="file:///$c/$_TAF/$reportHtml" title="(future function) Run TAF-Team Version based on IIS/http"> $web_ui_title </a></h2>
<ul>
EOF
find(sub { if ($File::Find::name =~ /index\.htm$/i) {
			my $tmp= $File::Find::name; $tmp=~ s/$SvrDrive//;
			my $tmp1 = $File::Find::name; $tmp1 =~ s/\/index.htm//g; $tmp1 =~ s/\/$reportHtml//; 
			my $tmp2 = $File::Find::name; $tmp2 =~ s/\/index.htm//g;
			my $testsuite = $tmp2;
			if ($tafProperty{$tmp2} ) { $tmp2 = sprintf("%-${tsPropertyWidth}s", $tafProperty{$tmp2}); }  
			else { $tmp2 = sprintf("%-${tsPropertyWidth}s", $tmp2); }
			$tafUI{$tmp2}=" <marquee style=\"border:RED 0px SOLID\" width=48 direction=right behavior=alternate loop=10000 scrollamount=".&getTSMaxScrollAmount($testsuite).">*</marquee> <a href=\"$url".$tmp."\">$tmp2</a><a style=\"color:silver\">$SvrDrive$tmp</a>\n" if ($tmp ne "/index.htm");
		}
	 }, $SvrDrive);

 	foreach my $each1 (sort keys %tafUI) { print INDEX $tafUI{$each1}; }

print INDEX <<EOF;
</ul>
</pre></body></html>
<style type="text/css"> a { text-decoration:none} </style>
EOF
;
close INDEX;
  		move ($SvrDrive.'/index.htm_', $SvrDrive.'/'."index.htm");
	#### 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;
  		move ($SvrDrive.'/index_http.htm_', $SvrDrive.'/'."index_http.htm");
	#### part 2 ####
1;
}



####################### 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*<span\s+style="color:black;/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 {
#######################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) { ;
			} elsif (&getLatestPassFail($_) =~ /color:black;/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:black;/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:black;/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:black;/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 

#######################generate_tagsHtml
sub generateTagHtml {
	my $index= shift; my $index_;
	my $tagName = "_smoke_"; 
	if ($index=~ /index\.htm\s*$/ ) {
		$index_ = $index;
		$index_ =~ s/\.htm/_$tagName\.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_${tagName}\.htm/g; }
				if (&processProperties("","dir", $tagName) =~ /color:green;/i) { print Fout $_; } # here to start
			}
			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;
		}
	}	
}
#######################generate_tagsHtml




sub getLatestPassFail {
	$_ = shift; my $color; my @symbol = $_ =~ />.<\/a><a\s+style=/g; my @color  = $_ =~ /<a style=\"color:\w+\"/g; 
for (my $i = 0; $i < $#symbol; $i++) { 
	$symbol[$i] =~ />(.)</; $symbol[$i] = $1;
	if ($symbol[$i] =~ /^\s*$/) {;}  # dumy 
	elsif ($symbol[$i] =~ /\|/) {;}  # mark
	else { $color[$i] =~ /\"(color:\w+)\"/; return "$1;"; }
}
return "";
}
sub getLatestPassFail_old {
	$_ = shift; my $color;
	if ($_ =~ /^\s*<span\s+style="color:black;">/) {
		# if ($_ =~ /^\s*<span\s+style="color:black;">\s*<a\s+style="color:\s*(\w+)"/) {$color = $1;} else {$color = "gray";}
		if ($_ =~ /^\s*<span\s+style="color:black;">\s*<a\s+style="color:\s*(\w+)"/) {$color = $1;} else {$color = "black";}
	}
	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 hungryMatch {    # hungryMatch("startStr_returnStr_endStr","startStr","endStr")
    my $str        = shift; my $startStr    = shift; my $endStr    = shift;

    if (index($str, $startStr) < 0) { return "";}
    if (index($str, $endStr  ) < 0) { return "";}
    my $offset     = index($str,$startStr) + length $startStr;
    my $len     = index($str,$endStr)  - $offset;
    if ($len < 0) { $len = 0; }
    return substr ($str, $offset, $len);
}
sub updateTestsuiteHTA {
	open Fin, $SvrDrive."/index.htm" || die "Can't open index.htm";
	while ($_ = <Fin>) { chop; if ( &hungryMatch($_,"\/\/\/","index.htm") ) { my $ts= &hungryMatch($_,"\/\/\/","index.htm") ; &createTestsuiteHTA ($ts); } }
	close Fin;
}

sub tsPostProcessPlugin {
	open Fin, $SvrDrive."/index.htm" || die "Can't open index.htm";
	while ($_ = <Fin>) { chop; if ( &hungryMatch($_,"/\/\/\/","index.htm")) { my $ts= &hungryMatch($_,"\/\/\/","index.htm"); print "postProcessPlugin: $ts\n";} }
	close Fin;
}
sub updateTestsuitePassFail {
	if (-e $SvrDrive."/index.htm" ) {
	open FinIndex, $SvrDrive."/index.htm" || die "Can't open index.htm";
	while ($_ = <FinIndex>) { chop; 
		if ( &hungryMatch($_, "\/\/\/","index.htm" )) { 
			my $ts     = &hungryMatch($_,"\/\/\/","index.htm")."index.htm" ; &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\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;
		$tafPropertyRev{$tcdesc} = $tcname;
		}
	}
	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)); 
    		my $fileText_= &readFile(&getTCLogFname_($tcname)); # for _tcLogAppendix_.txt (pyAnvil logs)
    		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_ 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*$/) || (&getTCLogFname_ ($tcname) =~ /_tcLogAppend_\.txt\s*$/) ||(&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)); 
    		my $fileText_ = &readFile(&getTCLogFname_($tcname)); # for _tcLogAppendix_.txt (pyAnvil logs)
    		my $fileText__= &readFile(&getTCLogFname__($tcname)); # for _tcLogAppendix_.txt (pyAnvil logs)

		######## add html tags to $fileText_ #######  
		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_ 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) ;
	 rmtree &getTCLogFname_ ($tcname) ;
	 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/</_lessThan/g; s/>/_greaterThan/g;s/=/_equal/g;
		s/"/_doubleQuote/g;
		s/'/_singleQuote/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; s/_lessThan/</g; s/_greaterThan/>/g;s/_equal/=/g;
		s/_doubleQuote/"/g;
		s/_singleQuote/'/g;
		if (($_ !~ /href=\"/) && ($_ =~ /(.+)($c\S+)\s?(.+)?/i)) { # convert c:\abc.txt  <a href file= abc.txt </a>
			my $match1 = $1; my $match2 = $2; my $match3=""; if ($3) {$match3 = $3;}

			if ($match2 =~ /\.txt\s*$/) { 
			my $currentTime  = &UnixDate( "now", "%m-%d-%Y-%H_%M_%S" );
			my $fileFrom = $match2; 
			my $fileTo   = $match2; $fileTo =~ s/\.txt\s*$/_$currentTime\.txt/;
			copy ($fileFrom, $fileTo);
			$return = $return.$match1."<a href=\"file:////$fileTo\">$fileTo</a>$match3\n";
			} else {
			$return = $return.$_."\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 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 = '';  

	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+/) { # always skip
		$_ =~ /^\s+(\w+)\s+\w+\s+(\d+\-\d+\-\d+\s+\d+:\d+:\d+)\s+/;
		$passFail = $1; $dateTime= $2; $date1=&ParseDate($dateTime);  my $title=" title=\"$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"'.$title.'>*</a>';	} 
		elsif ($passFail =~ /fail/i) { $passFail = '<a style="color:red"'.$title.'>*</a>';} 
		elsif ($passFail =~ /mark/i) {$passFail ="<a style=\"color:black\"$title>$markSymbol<\/a>";}
		elsif ($passFail =~ /Perf/i) {$passFail ="<a style=\"color:black\"$title>.<\/a>";}
		elsif ($passFail =~ /null/i) {$passFail ="<a style=\"color:black\"$title>.<\/a>";}
		elsif ($passFail =~ /dumy/i) {$passFail ="<a style=\"color:black\"$title> <\/a>";}
		elsif ($passFail =~ /expF/i) {$passFail ="<a style=\"color:black\"$title>*<\/a>";}
		$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+)/;
		$_ =~ /^\s+(\w+)\s+\w+\s+(\d+\-\d+\-\d+\s+\d+:\d+:\d+)\s+(.+)/;
		my $note=$3;
		$passFail = $1; $dateTime= $2; $date2=&ParseDate($dateTime); 
		my $title = " title=\"$dateTime $note\""; 

		if ($passFail =~ /pass/i) { $passFail = '<a style="color:green"'.$title.'>*</a>';	} 
		elsif ($passFail =~ /fail/i)  { $passFail = '<a style="color:red"'.$title.'>*</a>';} 
		elsif ($passFail =~ /null/i) { $passFail = '<a style="color:black"'.$title.'>.</a>';}
		elsif ($passFail =~ /mark/i) {$passFail ="<a style=\"color:black\"$title>$markSymbol<\/a>";}
		elsif ($passFail =~ /Perf/i) {$passFail ="<a style=\"color:black\"$title>.<\/a>";}
		elsif ($passFail =~ /null/i) {$passFail ="<a style=\"color:black\"$title>.<\/a>";}
		elsif ($passFail =~ /dumy/i) {$passFail ="<a style=\"color:black\"$title> <\/a>";}
		elsif ($passFail =~ /expF/i) {$passFail ="<a style=\"color:black\"$title>*<\/a>";}
		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,"");
	### here &readTCDesc_from_index($SvrDrive.'/'.$SvrProjName.'/index.htm'); 
 	&appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"<html><body><pre>\n");
find(sub { if (  ($File::Find::name =~ /tc.pl\s*$/) && ($File::Find::name =~ /$SvrDrive\/$SvrProjName\/$testcaseNode/i) && ($File::Find::name =~ /$SvrTCNamePattern/i)  ) { # fix tcDesc tag related 
			$SvrTCName = $File::Find::name; 
			$SvrTCName =~ s/\/tc.pl//g;
	my $fileText = sprintf "%10s %s", "", &reportTC($tcname,"","History");
	if ($tcDesc[$tcIdCtr]) {;} else { $tcDesc[$tcIdCtr] ="tcDesc is unavailable. It will be updated in next \"list\"";}
	&appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory, " ---- TestCase $tcIdCtr: <a name=\"".&getTCName($tcname)."\"> ".&processProperty("",$SvrTCName, "get_tcDesc")."</a>----\n");
	&appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory, $fileText);
	$tcIdCtr++;
		}
	 }, "$SvrDrive/$SvrProjName");
 	&appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"</pre></body></html>\n")				;
	$tcIdCtr = $tcIdCtr_;
}


sub reportTCHistory_old {
	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\s*$/) && ($File::Find::name =~ /$SvrDrive\/$SvrProjName\/$testcaseNode/i) && ($File::Find::name =~ /$SvrTCNamePattern/i)  ) { # fix tcDesc tag related 
			$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=""; 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;

    my $passFailDisplayWidth_1st= 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"; $comment2 = "Perf Test = ${1}s";}
		if ($propertyValue =~ /null/i) 		   {                           ;                        ; $comment2 = "TC returns NULL";}
		if ($propertyValue =~ /expF/i) 		   {                           ;                        ; $comment2 = "Expected Fail"  ;}
		if ($propertyValue =~ /expected_f_a_i_l/i) {                           ; $propertyValue = "expF"; $comment2 = "Expected Fail"  ;}

             if ( $isInSpan == 1 ) {
		 if ( $propertyPattern =~ /tcRunResult/i ) {
		      $beautifiedStr = sprintf "%15s %-15s %-25s%-20s Note: %s", $propertyValue, $totalSec.'s', $startTime, $comment1, $comment2; # add comment2 for mouse-over display
		      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";}
		      if ($propertyValue =~ /Perf/i) {          ; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."e";}
		      if ($propertyValue =~ /null/i) {          ; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."n";}
		      if ($propertyValue =~ /expF/i) {          ; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."x";}
		      if ($propertyValue =~ /dumy/i) {          ;                                   ; $passFailDisplay = $passFailDisplay."d";}
		      if ($propertyValue =~ /expected_F_a_i_l/i) {; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."x";}

		      if ($propertyValue =~ /pass/i) {                                                $passFailDisplay_ = $passFailDisplay_."p $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /fail/i) {                                                $passFailDisplay_ = $passFailDisplay_."f $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /mark/i) {                                                $passFailDisplay_ = $passFailDisplay_."m $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /Perf/i) {                                                $passFailDisplay_ = $passFailDisplay_."e $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /null/i) {                                                $passFailDisplay_ = $passFailDisplay_."n $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /expF/i) {                                                $passFailDisplay_ = $passFailDisplay_."x $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /dumy/i) {                                                $passFailDisplay_ = $passFailDisplay_."d $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /expected_f_a_i_l/i) {  				      $passFailDisplay_ = $passFailDisplay_."x $startTime: ${comment2}_|_";}
		      if ($propertyValue =~ /pass|fail|mark|Perf|null|expF/i) { $passFailDisplayWidth_1st ++ ; }
		 } 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/
    }									##################### 

    ############################## Adjust passFailDisplayWidth by _1st and max ###########################
 	if ( $passFailDisplayWidth < $passFailDisplayWidth_1st ) { $passFailDisplayWidth = $passFailDisplayWidth_1st;}
 	if ( $passFailDisplayWidth > $maxPassFailDisplayWidth  ) { $passFailDisplayWidth = $maxPassFailDisplayWidth ;}
    ############################## 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 ) { 
		$TCDesc_display = sprintf "%-${webUI_TCDescWidth}s", $TCDesc_display_; 
		} else {
		$TCDesc_display = sprintf "%-${webUI_TCDescWidth}s", substr $TCDesc_display_, 0, $webUI_TCDescWidth; 
		$TCDesc_displayTip = $tsProperty{$tcname}; 
		}

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

	# prHtml3 mark for search

	my $perl = $^X;  $perl =~ s/\\/\\\\/g;
	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 $stopTS    = "<a href=\"${url}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName exitTAFGracefullyString=$tcname;exitTAF')\" title=\"Stop Test (Testcase Number = $tcSerialN)\" >.</a>";
	my $runTS24_7 = "<a href=\"${url}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName -s drive=$SvrDrive;tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;testcaseExec=$dirRoot;ExecutionType=runTC;Execution_24_7=y;exec')\"  title=\"Exec Test 24/7 (Testcase Number == $tcSerialN)\"> ,</a>"; 
	my $runTCOnce = "<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\">></a>";
	my $runTSOnce = "<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>>\|</marquee></a>"; 
	$passFailDisplay  = &genPassFailDisplay ($passFailDisplay);
	$passFailDisplay = &genPassFailDisplay_ ($passFailDisplay_);
	my $html = sprintf( "<span style=\"color:black;\">$passFailDisplay${stopTS}$runTS24_7<font color=\"$color[$colorIndex]\"> $runTCOnce $runTSOnce</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 $html_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, $html 		);
			&updateWeb1_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml, $html			);  

			 	&appendtoFileUniq_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1_http, $html_http 	); 
			&updateWeb1Http_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml_http, $html_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 genPassFailDisplay_ {
	my $str = shift; my $str_ =""; my $strLenCtr=0; my $mark4One=0;
	@_ = split /_\|_/, $str; $str="";
	for (my $i=$#_; $i >= 0; $i--) { 
		my $tcResult ; 
		if( $_[$i] =~ s/^\s*(\w)\s+//g) {
			$tcResult = $1; $str_ = $_[$i];  $strLenCtr++;
			if ($tcResult =~ /p/i)    { $str = $str."<a style=\"color:green\" title=\"$str_\">*<\/a>"; }
			elsif ($tcResult =~ /f/i) { $str = $str."<a style=\"color:red\" title=\"$str_\">*<\/a>";   }
			elsif ($tcResult =~ /m/i) { 
				#if ($mark4One == 2) { ; } else {
				$str = $str."<a style=\"color:black\" title=\"$str_\">$markSymbol<\/a>"; 
				#$mark4One = 0; 
			}

			elsif ($tcResult =~ /e/i) { $str = $str."<a style=\"color:black\" title=\"$str_\">.<\/a>"; }
			elsif ($tcResult =~ /n/i) { $str = $str."<a style=\"color:black\" title=\"$str_\">.<\/a>"; }
			elsif ($tcResult =~ /x/i) { $str = $str."<a style=\"color:black\" title=\"$str_\">*<\/a>"; }
			elsif ($tcResult =~ /d/i) { $str = $str."<a style=\"color:black\" title=\"$str_\"> <\/a>"; }
			elsif ($tcResult =~ /_/i) { $str = $str."<a style=\"color:black\" title=\"$str_\">.<\/a>"; }
		}
			$mark4One++; 
		if ($strLenCtr + 1 > $passFailDisplayWidth) { return $str; }
	} 
	if ($strLenCtr < $passFailDisplayWidth) { for (my $i = $strLenCtr; $i < $passFailDisplayWidth; $i++) { $str = $str . "<a style=\"color:black\"> <\/a>"; } }
	return $str; 
}

sub genPassFailDisplay_old {
	my $str = shift; my $str_ =""; my $strLenCtr=0;
	@_ = split /_\|_/, $str; $str="";
	for (my $i=$#_; $i >= 0; $i--) { 
		my $tcResult ; 
		if( $_[$i] =~ s/^\s*(\w)\s+//g) {
			$tcResult = $1; $str_ = $_[$i];  $strLenCtr++;
			if ($tcResult =~ /p/i)    { $str = $str."<a style=\"color:green\" title=\"$str_\">*<\/a>"; }
			elsif ($tcResult =~ /f/i) { $str = $str."<a style=\"color:red\" title=\"$str_\">*<\/a>";   }
			elsif ($tcResult =~ /m/i) { $str = $str."<a style=\"color:black\" title=\"$str_\">|<\/a>"; }
		}
		if ($strLenCtr + 1 > $passFailDisplayWidth) { return $str; }
	} 
	if ($strLenCtr < $passFailDisplayWidth) { for (my $i = $strLenCtr; $i < $passFailDisplayWidth; $i++) { $str = $str . "<a style=\"color:blank\"> <\/a>"; } }
	return $str; 
}

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

sub processTSs{
	shift;
 	my $each = shift;
		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); }
				elsif ($varName =~ /\bcheckStatus\b/i) { &checkStatusTS($varValue); }
				else {
					print "Unrecognized Testsuite Command: $varName\n"; 		
				}
			}
		}
}

sub checkStatusTS {
	print "pass a: ".shift."\n";
}
sub processTCs{
	shift;
	my $isBatchProcessing = 1;
	my $tmp = shift;
	@_ = split /;/, $tmp;
	&genDriver_taf_pl ();
		&appendtoFile($commandLogName, "\n".&UnixDate( "now", "%m/%d/%Y %H:%M:%S %Z")."> ");
		&appendtoFile($commandLogName,"$c/$_TAF/$taf ");
	foreach my $each (@_) {
		#### uncomment for debugging   print " cmd> $each\n";
		print " cmd> $each\n";
		&appendtoFile($commandLogName,$each.";");
		if ($each !~ /=/) {
			$isBatchProcessing = 0;
			if (($each =~ /\blistVars\b/i) || ($each =~ /\bgetVars\b/i)) { return &printGlobalVars()	;
			} elsif ($each =~ /\bprintVars\b/i) { print &printGlobalVars(); 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 =~ /\blistHistory\b/i) { 							;
				&setGlobalVars("","tcOP=listHistory")							;
				$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*$/)) {

				if ($varName =~ /propertyOp/) { $isBatchProcessing = 1; } else { $isBatchProcessing = 0;} # 1 for propertyOp
				if (&setGlobalVars ("","$varName=$varValue;") == 1 ) 		{ ; }
				else {
					my $rst = &processTC("",$each) 			;
				}
			}
			} else { next; } 
		}
	if ($isBatchProcessing == 1) { $NofExecutionCtr=0; &tcLoop();}		# NofExecutionCtr reset for each list/exec
	} 
}

################################################################################
#	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;
	    ######## 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 $tmp = sprintf "%-20s %-40s\n", "processTC: ", $tcname   ;
 	    &appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'."_listHistory.txt", "$tmp");
	    my $rst; 

	    if ( $tcOP =~ /^\s*create/i ) {
		    if ($cmd) { $rst = &createTC("cmd=$cmd",$tcname); }
		    else { $rst = &createTC($tcname); }
            } elsif ( $tcOP =~ /^\s*exec\b/i ) {
		    #if ($makeMark =~ /y/i) {$rst = &markTC_($tcname);}
		    if ($NofExecutionCtr== 1 ) {$rst = &markTC_($tcname);}
		    $rst = &execTC_($tcname);
		    my $rst1 = &mapTC($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*listHistory/i ) {
		    $rst = &getProperties(&getTCName($tcname) , 'tcRunResult', 'history');
            } elsif ( $tcOP =~ /^\s*printResult/i ) {

	    } elsif ( $tcOP =~ /^\s*list|get\b/i ) {
		    #$rst = &getProperties(&getTCName($tcname) , 'tcRunResult', 'latest'); # return latest include dump TC
		    $rst = &getProperties(&getTCName($tcname) , 'tcRunResult', 'last');	   # return last valid TC result
		    my $rst1 = &mapTC($tcname);
            } 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
 	        &appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'."_listHistory.txt","$rst\n")				;
	 	$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 {		# Create Testsuite for Testbed 
	# my $tsName = "_testsuite_"; $tsName = shift if @_;
	my $tsName = $SvrProjName; $tsName = shift if @_;
	####### here if ($SvrProjName ne "_testsuite_") { $tsName = $SvrProjName; } # for backwards compatibility
	$SvrProjName = $tsName;
	if ($SvrProjName =~ s/_powershell_//i)  { 
		my $rst = mkpath $SvrProjName ; print " --> Create Powershell Testsuite: $SvrProjName\n";
		&generatePowershell_ps1_template(); 
	} else { 
		my $rst = mkpath $SvrProjName; print " --> Create Perl Testsuite: $SvrProjName\n";
		&generatePerl_pl_template(); 
	}
1;
}
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', 
"
<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 =~ /expF/i) { # ExpF for ExpectedFailedTC
		&createFile( $tcName.'\\'.$tc_pl, "\$| = 1; print \"expF\\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\");}
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\");}
if (-e \"$externalLogName\") {copy(\"$externalLogName\", \"$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\");}
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\");}
if (-e \"$externalLogName\") {copy(\"$externalLogName\", \"$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\");}
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\");}
if (-e \"$externalLogName\") {copy(\"$externalLogName\", \"$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_`;
"
			);
			###########
				;
			} elsif ( $cmd =~ /powershellTC/) {
			###########
			&createFile( $tcName.'\\'.$tc_pl, 
"
"
			);
			###########
				;
			} 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|expF|todo|[\d|.]+)$/i; $rst = $1; 
	       if ($rst) {;} else {$rst = "null";} 
	       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 dumyTC_ {	# create a dumy tc result 
	my $tcName = &getTCName(@_);
	my $timeStart = &getDate(); my $rst=''; 
	if  ( -e "$tcName/$tc_pl" ) { 
		my $cmd     = "$tcName/$tc_pl"; $rst = "dump"; 
		my $timeEnd= &getDate(); 
	       $rst = "dumy";
	       if ($rst) {;} else {$rst = "null";}
	       my $rstStr = sprintf "%20s|%10s|%s", "tcRunResult",$rst , $timeStart;
	       $rstStr .= "|"; $rstStr .= "$timeEnd"; $rstStr .= "|"; $rstStr .= "0:0:0:0s";
	       $rstStr .= "|"; 
	       $rstStr .= "Functional Test ($rst) ";
	       $rstStr .= '|'.$tcComment2; 
	       &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|expF|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 .= '|'.$tcComment2; 
	       &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|expF|expected_f_a_i_l|[\d|.]+)$/i; $rst = $1; 
	       if ($rst) {
	       	if ($rst =~ /expected_f_a_i_l/) { $rst = "expF"; }
		       ;} 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 mapTC {
	my $tcName = &getTCName(@_);
	my $timeStart = &getDate(); my $rst=''; 
	if  ( -e "$tcName/$tc_pl" ) { 
	       if (-e "$c/$_TAF/$SvrProjName/_tcMap.txt") {
		       my $tcName_ = &getTCName($tcName); $tcName_ =~ s/$c\/$_TAF\///i;
			&mergethProperty($tcName_,"$c/$_TAF/$SvrProjName/_tcMap.txt");
		       }
	        return $rst;
       } else {
		return "tcName: $tcName doesn't exist.\n";
       }
}

sub mergethProperty {
my $thPropertyString ="_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_pl/testcase0002"; $thPropertyString= shift if @_; 
my $tcMapFName = "_tcMap.txt"; $tcMapFName = shift if @_;
my $propertyName = "tcRunResult";my  %records; my %record_out; my $tag = "tag"; my $content_out=""; my $parent=""; my $child;
open Fin, $tcMapFName;
 	while ($_=<Fin>) { chop;
  		if ($_ =~ /$thPropertyString/) { 
			my $thPropertyFName;
			$content_out = "";
			 ($parent, $child) = split (/\s*=>\s*/, $_);
			if (($parent !~ /^\s*$/) && ($child !~ /^\s*$/)) {	
			$thPropertyFName=$parent."/thProperty.txt"; if ($thPropertyFName !~ /$c\/$_TAF/) {$thPropertyFName =~ s/$c/$c\/$_TAF/;} # TS->TAF TS conversion 
			open Fin1, $thPropertyFName or die "Can't open $thPropertyFName:$!";  
			while ($_ = <Fin1>) { 
				# if ($_ =~ /_(regressiontest|smoketest|bat)_/) { $tag=$1;}	# todo
				if ($_ =~ /$tags/) { $tag=$1;}	# todo
				if ($_ =~ /^\s*$propertyName\s*\|/) { @_ = split (/\|/, $_); $records{$_[2]}=$_; } 
				else { $content_out = $content_out.$_; }
			} 
			close Fin1;
			$thPropertyFName=$child."/thProperty.txt";    if ($thPropertyFName !~ /$c\/$_TAF/){ $thPropertyFName =~ s/$c/$c\/$_TAF/;} # TS->TAF TS conversion 
			open Fin1, $thPropertyFName or die "Can't open $thPropertyFName:$!";  
			while ($_ = <Fin1>) { 
				if ($_ =~ /$tags/i) { $tag=$1;}	# todo
				if ($_ =~ /^\s*$propertyName\s*\|/) { $_ =~ s/Comment2\s*$/$tag/i; @_ = split (/\|/, $_); $records{$_[2]}=$_; 
				} 
			} 
			close Fin1;
			}
		}
 	} 
close Fin;
	if (-e $parent) {
		open Fout1, ">$parent/thProperty.txt_"; 
		print Fout1 $content_out; 
		foreach my $each (sort keys %records) { print Fout1 "$records{$each}\n"; } 
		close Fout1;
		print " -> $parent/thProperty.txt_ (needs to use copyFile)";
		&copyFile("$parent/thProperty.txt_", "$parent/thProperty.txt");
	}

}
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 getTSName {
	my $tsname = shift;
	$tsname =~ s/\/testcase\d+.+//g;
	return $tsname;
}

sub getTCName {
	my $SvrProjNameTmp; my $SvrDriveTmp; my $SvrTCNameTmp="" ;  
	$SvrTCNameTmp = shift if @_; 
	if ($notUsegetTCName==1) 	{ return   $SvrTCName;				}	# Do nothing
	if ($SvrTCNameTmp) 		{;} else { $SvrTCNameTmp = $SvrTCName; 		}  	# get current SvrTCName 
	if ($SvrProjNameTmp) 		{;} else { $SvrProjNameTmp = $SvrProjName;	}  	# do nothing
	if ($SvrDriveTmp) 		{;} else { $SvrDriveTmp = $SvrDrive;		}  	# do nothing
	if ($SvrTCNameTmp =~ /[a-z]:/i) { return   $SvrTCNameTmp;			}	# remove c:
	else { return ($SvrDriveTmp.'/'.$SvrProjNameTmp.'/'.$SvrTCNameTmp) ; 		}	# c:/testcase/testsuite
}

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*_?modify_(.+)_(as|eq)_(.+)/) { $propertyOP = "add_eq_$1_column_$3"; }
	if ($propertyOP =~ /^\s*_?set_(.+)_(as|eq)_(.+)/) { $propertyOP = "add_eq_$1_column_$3"; }
	elsif ($propertyOP =~ /^\s*_?get_history(.+)/)  { $propertyOP = "get_history$1"; }
	elsif ($propertyOP =~ /^\s*_?list_history(.+)/) { $propertyOP = "get_history$1"; }

	elsif ($propertyOP =~ /^\s*_?get_latest(.+)/)  { $propertyOP = "get_latest$1"; }
	elsif ($propertyOP =~ /^\s*_?list_latest(.+)/) { $propertyOP = "get_latest$1"; }

	elsif ($propertyOP =~ /^\s*_?get_last(.+)/)  { $propertyOP = "get_last$1"; }
	elsif ($propertyOP =~ /^\s*_?list_last(.+)/) { $propertyOP = "get_last$1"; }

	elsif ($propertyOP =~ /^\s*_?get_(.+)/) { $propertyOP = "get_$1"; }
	elsif ($propertyOP =~ /^\s*_?list_(.+)/) { $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_history|list_history_/i ) {
		$propertyOP =~ s/^\s*get_history_+\s*//g; $propertyOP =~ s/^\s*list_history_+\s*//g;
		$rst = &getProperties(&getTCName($tcname), $propertyOP, "history" );
 	}
        elsif ( $propertyOP =~ /^\s*get_latest|list_latest/i ) {
		$propertyOP =~ s/^\s*get_latest_+\s*//g; $propertyOP =~ s/^\s*list_latest_+\s*//g;
		$rst = &getProperties(&getTCName($tcname), $propertyOP, "latest" );
 	}
        elsif ( $propertyOP =~ /^\s*get_last|list_last/i ) {
		$propertyOP =~ s/^\s*get_last_+\s*//g; $propertyOP =~ s/^\s*list_last_+\s*//g;
		$rst = &getProperties(&getTCName($tcname), $propertyOP, "last" );
 	}
        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 ) {
		if ($propertyOP =~ s/^\s*match\s*_//g) {
		    $propertyOP =~ /\s*(\S+)\s*_(as|eq)_\s*(\S+)\s*/; 
		    # $propertyOP =~ /\s*(\S+)\s*[:|;]\s*(\S+)\s*/; 
        	    $rst = &matchProperty($1, $3, $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), "", "_all_")) {
		$each =~ /^\s*(\w+)\s+(\w+)\s*$/;
		$array {$1}  = $2;
	}
	foreach my $each (sort keys %array) {
		if (($array{$each} =~ /$propertyPattern/) && ( $each =~ /$propertyName/)) { 
			 return "True\n$each:$array{$each}"; }
	}
	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 @_ ;

    		if ($propertyOp =~ s/^\s*add\s*=\s*//ig) {;}
		elsif ($propertyOp =~ s/^\s*_eq_\s*//g) {;}
		elsif ($propertyOp =~ s/\s*_eq_\s*/=/g) {;}
		elsif ($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; my $propertyStartTime = $_[2];
	    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 \@ $propertyStartTime\n",$propertyName_, $propertyValue_;
			} elsif ($returnType =~ /\blatest\b/i) {
				$returnValue = "$propertyValue_\n";
			} elsif ($returnType =~ /\blast\b/i) {
				if ($propertyValue_ !~ /dumy/) { $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];
    my $propertyValue       ; 
    if ($propertyName =~ s/^\s*modify\s*_\s*//g) {
    $propertyName =~ /(\w+)\s*_as_\s*(\w+)\s*/;
    $propertyName = $1; $propertyValue = $2;
    }
    my $cmdStr        = "delete=$propertyName";
    &deleteProperty( $tcname, $cmdStr );
    # $cmdStr = "add=$propertyName:$propertyValue";
    $cmdStr = "add_${propertyName}_column_${propertyValue}"; # todo
    &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";} else {
    $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 $tcDesc = "@_"; 
    my $fname = "@_\\thProperty.txt";
    open Fout, ">$fname";
    printf Fout "%20s|%10s%s\n", 'tcId','null',$timeStr;
    printf Fout "%20s|%10s%s\n", 'tcDesc',$tcDesc,$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*/; 
		# $propertyName =~ /^\s*(\S+):(\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;
		$propName =~ s/_space_/ /g;
        	printf "%20s|%10s%s\n",$propName, $propValue,$timeStr;
        	printf Fout "%20s|%10s%s\n",$propName, $propValue,$timeStr;
		}
	}
    close Fout;
    return "$propertyName is added to $fname";
}

sub printGlobalVars {
my $return=<<EOF;
##################### Frequently Used Setting ####################
web_ui_title                  =$web_ui_title                  
tags                          =$tags                          
ps1_args                      =$ps1_args                      
Execution_24_7                =$Execution_24_7                
##################### WebUI Setting           ####################
excelReportColumnWidth        =$excelReportColumnWidth        
pr2Screen                     =$pr2Screen                     
webUI_TCDescWidth             =$webUI_TCDescWidth             
scrollAmount                  =$scrollAmount                  
borderWidth                   =$borderWidth                   
borderStyle                   =$borderStyle                   
passFailDisplayWidth          =$passFailDisplayWidth          
maxPassFailDisplayWidth       =$maxPassFailDisplayWidth       
##################### TAFA Default  Setting   ####################
c                             =$c                             
taf                           =$taf                           
_TAF                          =$_TAF                          
reportHtmlSummaryScale        =$reportHtmlSummaryScale        
reportHtmlSummaryScaleMajor   =$reportHtmlSummaryScaleMajor   
tsPropertyWidth               =$tsPropertyWidth               
NofExecution                  =$NofExecution                  
ExecutionLength               =$ExecutionLength               
tsFilter                      =$tsFilter                      
tcComment1                    =$tcComment1                    
tcComment2                    =$tcComment2                    
MaxTCExecTime                 =$MaxTCExecTime                 
TSHookName                    =$TSHookName                    
TSHookNameGenerated           =$TSHookNameGenerated           
interact                      =$interact                      
tcPropertyPatternName         =$tcPropertyPatternName         
tcPropertyPatternPattern      =$tcPropertyPatternPattern      
tcPropertyPatternName1        =$tcPropertyPatternName1        
tcPropertyPatternPattern1     =$tcPropertyPatternPattern1     
tcPropertyPatternName2        =$tcPropertyPatternName2        
tcPropertyPatternPattern2     =$tcPropertyPatternPattern2     
tcPropertyPatternName3        =$tcPropertyPatternName3        
tcPropertyPatternPattern3     =$tcPropertyPatternPattern3     
tcPropertyName                =$tcPropertyName                
tcNamePattern                 =$tcNamePattern                 
tcOp                          =$tcOp                          
tcCtr                         =$tcCtr                         
tcDelta                       =$tcDelta                       
markSymbol                    =$markSymbol                    
tsFilterDefault               =$tsFilterDefault               
tcFilterDefault               =$tcFilterDefault               
SvrDrive                      =$SvrDrive                      
SvrProjName                   =$SvrProjName                   
SvrTCName                     =$SvrTCName                     
SvrTCNamePattern              =$SvrTCNamePattern              
SvrPropNamePattern            =$SvrPropNamePattern            
SvrPropValuePattern           =$SvrPropValuePattern           
SvrTCNameExecPattern          =$SvrTCNameExecPattern          
exitTAFGracefullyLock         =$exitTAFGracefullyLock         
performanceMode               =$performanceMode               
resetTSFileName               =$resetTSFileName               
externalLogName               =$externalLogName               
commandLogName                =$commandLogName                
commandLogLifeSpan            =$commandLogLifeSpan            
testType                      =$testType                      
AutomationtsName              =$AutomationtsName              
tsProperty                    =$tsProperty                    
sleep4Display		      =$sleep4Display
EOF
}


sub readTAFGlobalVars {
open Fin, "c:/_TAF/_tafGlobalVars.txt"; 
while (<Fin>) { chop;
	if ($_ =~ /(.+)=(.+)/ ) { &readTAFGlobalVars1($1, $2); }
	}
close Fin;
}
sub readTAFGlobalVars1 {
	my $varName  = shift;
	my $varValue = shift;
if ($varName eq "web_ui_title"                ) { $web_ui_title                   = $varValue; }
if ($varName eq "tags"                        ) { $tags                           = $varValue; }
if ($varName eq "ps1_args"                    ) { $ps1_args                       = $varValue; }
if ($varName eq "excelReportColumnWidth"      ) { $excelReportColumnWidth         = $varValue; }
if ($varName eq "pr2Screen"                   ) { $pr2Screen                      = $varValue; }
if ($varName eq "webUI_TCDescWidth"           ) { $webUI_TCDescWidth              = $varValue; }
if ($varName eq "scrollAmount"                ) { $scrollAmount                   = $varValue; }
if ($varName eq "borderWidth"                 ) { $borderWidth                    = $varValue; }
if ($varName eq "borderStyle"                 ) { $borderStyle                    = $varValue; }
if ($varName eq "passFailDisplayWidth"        ) { $passFailDisplayWidth           = $varValue; }
if ($varName eq "maxPassFailDisplayWidth"     ) { $maxPassFailDisplayWidth        = $varValue; }
if ($varName eq "reportHtmlSummaryScale"      ) { $reportHtmlSummaryScale         = $varValue; }
if ($varName eq "reportHtmlSummaryScaleMajor" ) { $reportHtmlSummaryScaleMajor    = $varValue; }
if ($varName eq "tsPropertyWidth"             ) { $tsPropertyWidth                = $varValue; }
if ($varName eq "c"                           ) { $c                              = $varValue; }
if ($varName eq "taf"                         ) { $taf                            = $varValue; }
if ($varName eq "_TAF"                        ) { $_TAF                           = $varValue; }
if ($varName eq "Execution_24_7"              ) { $Execution_24_7                 = $varValue; }
if ($varName eq "NofExecution"                ) { $NofExecution                   = $varValue; }
if ($varName eq "ExecutionLength"             ) { $ExecutionLength                = $varValue; }
if ($varName eq "tsFilter"                    ) { $tsFilter                       = $varValue; }
if ($varName eq "tcComment1"                  ) { $tcComment1                     = $varValue; }
if ($varName eq "tcComment2"                  ) { $tcComment2                     = $varValue; }
if ($varName eq "MaxTCExecTime"               ) { $MaxTCExecTime                  = $varValue; }
if ($varName eq "TSHookName"                  ) { $TSHookName                     = $varValue; }
if ($varName eq "TSHookNameGenerated"         ) { $TSHookNameGenerated            = $varValue; }
if ($varName eq "interact"                    ) { $interact                       = $varValue; }
if ($varName eq "tcPropertyPatternName"       ) { $tcPropertyPatternName          = $varValue; }
if ($varName eq "tcPropertyPatternPattern"    ) { $tcPropertyPatternPattern       = $varValue; }
if ($varName eq "tcPropertyPatternName1"      ) { $tcPropertyPatternName1         = $varValue; }
if ($varName eq "tcPropertyPatternPattern1"   ) { $tcPropertyPatternPattern1      = $varValue; }
if ($varName eq "tcPropertyPatternName2"      ) { $tcPropertyPatternName2         = $varValue; }
if ($varName eq "tcPropertyPatternPattern2"   ) { $tcPropertyPatternPattern2      = $varValue; }
if ($varName eq "tcPropertyPatternName3"      ) { $tcPropertyPatternName3         = $varValue; }
if ($varName eq "tcPropertyPatternPattern3"   ) { $tcPropertyPatternPattern3      = $varValue; }
if ($varName eq "tcPropertyName"              ) { $tcPropertyName                 = $varValue; }
if ($varName eq "tcNamePattern"               ) { $tcNamePattern                  = $varValue; }
if ($varName eq "tcOp"                        ) { $tcOp                           = $varValue; }
if ($varName eq "tcCtr"                       ) { $tcCtr                          = $varValue; }
if ($varName eq "tcDelta"                     ) { $tcDelta                        = $varValue; }
if ($varName eq "markSymbol"                  ) { $markSymbol                     = $varValue; }
if ($varName eq "tsFilterDefault"             ) { $tsFilterDefault                = $varValue; }
if ($varName eq "tcFilterDefault"             ) { $tcFilterDefault                = $varValue; }
if ($varName eq "SvrDrive"                    ) { $SvrDrive                       = $varValue; }
if ($varName eq "SvrProjName"                 ) { $SvrProjName                    = $varValue; }
if ($varName eq "SvrTCName"                   ) { $SvrTCName                      = $varValue; }
if ($varName eq "SvrTCNamePattern"            ) { $SvrTCNamePattern               = $varValue; }
if ($varName eq "SvrPropNamePattern"          ) { $SvrPropNamePattern             = $varValue; }
if ($varName eq "SvrPropValuePattern"         ) { $SvrPropValuePattern            = $varValue; }
if ($varName eq "SvrTCNameExecPattern"        ) { $SvrTCNameExecPattern           = $varValue; }
if ($varName eq "exitTAFGracefullyLock"       ) { $exitTAFGracefullyLock          = $varValue; }
if ($varName eq "performanceMode"             ) { $performanceMode                = $varValue; }
if ($varName eq "tsFrom"                      ) { $tsFrom                         = $varValue; }
if ($varName eq "tsTo"                        ) { $tsTo                           = $varValue; }
if ($varName eq "resetTSFileName"             ) { $resetTSFileName                = $varValue; }
if ($varName eq "externalLogName"             ) { $externalLogName                = $varValue; }
if ($varName eq "commandLogName"              ) { $commandLogName                 = $varValue; }
if ($varName eq "commandLogLifeSpan"          ) { $commandLogLifeSpan             = $varValue; }
if ($varName eq "testType"                    ) { $testType                       = $varValue; }
if ($varName eq "AutomationtsName"            ) { $AutomationtsName               = $varValue; }
if ($varName eq "tsProperty"                  ) { $tsProperty                     = $varValue; }
}


sub getGlobalVars_old { 
	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
	\$testcaseNode    	= $testcaseNode
	\$testType        	= $testType
	\$tsTo            	= $tsTo         
	\$tsFrom          	= $tsFrom
	\$sleep4Display 	= $sleep4Display
	\$makeMark      	= $makeMark
	\$externalLogName	= $externalLogName
	\$tags			= $tags
	
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 =~ /\btcPropertyName\b/i)  	{ $tcPropertyName = $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;} 
		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 =~ /\btppp1\b/i)  		{ $tcPropertyPatternPattern1= $varValue; $foundMatch = 1; $tcPropertyPatternPattern =~ s/_pipe_/\|/gi;}
		elsif ($varName =~ /\btppn1\b/i)		{ $tcPropertyPatternName1= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\btppp2\b/i)  		{ $tcPropertyPatternPattern2= $varValue; $foundMatch = 1; $tcPropertyPatternPattern =~ s/_pipe_/\|/gi;}
		elsif ($varName =~ /\btppn2\b/i)		{ $tcPropertyPatternName2= $varValue; $foundMatch = 1;}

		elsif ($varName =~ /\btppp2\b/i)  		{ $tcPropertyPatternPattern3= $varValue; $foundMatch = 1; $tcPropertyPatternPattern =~ s/_pipe_/\|/gi;}
		elsif ($varName =~ /\btppn2\b/i)		{ $tcPropertyPatternName3= $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;}
		elsif ($varName =~ /\bnotUsegetTCName\b/i)  	{ $notUsegetTCName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTSHookName\b/i)  		{ $TSHookName      = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bTSHookNameGenerated\b/i)  { $TSHookNameGenerated  = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btestcaseNode\b/i)  	{ $testcaseNode    = $varValue; $foundMatch = 1; } 
		elsif ($varName =~ /\btestType\b/i)  		{ $testType        = $varValue; $foundMatch = 1; 
			if ($testType =~ /tc/i) { $testcaseNode = ".*";}
			if ($testType =~ /ts/i) { $testcaseNode = "testcase";}
		} 
		elsif ($varName =~ /\btsFrom\b/i)  		{ $tsFrom          = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btsTo\b/i)  		{ $tsTo            = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bmakeMark\b/i)  		{ $makeMark        = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bexitTAFGracefullyString\b/i) { $exitTAFGracefullyString = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bAutomationtsName\b/i)     { $AutomationtsName= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bresetTSFileName\b/i)      { $resetTSFileName = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bexitTAFTCId\b/i)          { $exitTAFTCId 	   = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btcComment1\b/i)            { $tcComment1	   = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btcComment2\b/i)            { $tcComment2	   = $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bexternalLogName\b/i)       { $externalLogName= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\bexternalLogName\b/i)       { $externalLogName= $varValue; $foundMatch = 1;}
		elsif ($varName =~ /\btags\b/i)       		 { $tags= $varValue; $foundMatch = 1; 
		my $tmp = ""; foreach my $each (split (/_,_/, $tags)) { $tmp=$tmp."|".$each; } $tmp =~ s/\|_/_(/g; $tmp =~ s/_\s*$/)_/g; $tags =  $tmp;	
		}
	}
	$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";
	my $cwd = $SvrProjName; my $cmd = $SvrProjName. "\/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 generateExcelReport {
	my $key; my %listHistory; my %tcDesc; my @tcExecDateTime; my $tcExecDateTimeCtr=0; my $isPassFail = "n"; my $tsName= "MVSDK_OCSP"; my @columnWidth;
	#  todo: need some variable initialization 
	#	&processTCs ("","testsuite=$SvrProjName;AutomationtsName=$SvrProjName;resetTSFileName=_list_history_tcRunResult.txt;resetTSFile;propertyOp=list_history_tcRunResult");
	#       &processTCs ("","testsuite=$SvrProjName;AutomationtsName=$SvrProjName;resetTSFileName=_list_tcDesc.txt;resetTSFile;propertyOp=list_tcDesc"); 
	

 	  my $cmd ="$c/$_TAF/taf.pl testsuite=$SvrProjName;AutomationtsName=$SvrProjName;resetTSFileName=_list_tcDesc.txt;resetTSFile;propertyOp=list_tcDesc"; my $rst = `$cmd`;
 	  $cmd ="$c/$_TAF/taf.pl testsuite=$SvrProjName;AutomationtsName=$SvrProjName;resetTSFileName=_list_history_tcRunResult.txt;resetTSFile;propertyOp=list_history_tcRunResult"; $rst = `$cmd`;

	my $tcDescMax=40; my $tcIdMax=10;
	if ( -e "$SvrDrive/$SvrProjName/_list_tcDesc.txt") {
		##### print " <- $SvrDrive/$SvrProjName/_list_tcDesc.txt\n";
		open Fin, "$SvrDrive/$SvrProjName/_list_tcDesc.txt" || die "Can't open file $!"; 
		while( $_ = <Fin>) {
		chop; 
		$_ =~ s/(list_)?tcDesc\s*=\s*(\d+\.)?//; 
		if ($_ =~ /testcase\d+(_)?\s+/) { @_ = split (/\t/, $_); 
			my $key = $_[0]; my $value = $_[1];	
			if ($_ =~ /\/_/)  {;} else { # exclude directory like /_ 
				$value =~ s/_.+_//g; # remove property
					}
			$tcDesc{$key} = $value; 
			if (length($value) > $tcDescMax) { $tcDescMax = length ($value); }
			if (length($key) > $tcIdMax) { $tcIdMax = length ($key); }
		} 
		} 
	close Fin;	
	;} else { 
	print "Info: $SvrDrive/$SvrProjName/_list_tcDesc.txt doesn't exist. Proceed ... (generateExcelReport won't work. Run -propertyOp=list_tcDesc)\n"; return 0 ;}

	$columnWidth[0]=$tcIdMax; $columnWidth[1]=$tcDescMax;

	if ( -e "$SvrDrive/$SvrProjName/_list_history_tcRunResult.txt") {
	####		print " <- $SvrDrive/$SvrProjName/_list_history_tcRunResult.txt\n";
	open Fin, "$SvrDrive/$SvrProjName/_list_history_tcRunResult.txt" || die "Can't open file $!"; 
	while($_ = <Fin>) { chop; s/\s*=\s*/ /g;
		if ($_ =~ /list_history_tcRunResult/) { 
			if ($_ =~ /list_history_tcRunResult/) { $tcExecDateTimeCtr ++ ;}
			@_ = split (/\s+/, $_); 
			$_ =~ /(.+)\s+(.+)/;
			$key 	= $_[0]; my $value 	= $_[1];
			if ($_ =~ s/^.+list_history_tcRunResult//) {
				my $passFail=""; my $date="";
				if ($_ =~ /tcRunResult\s*(\S+)\s+\@\s+(\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d:\d\d)/ ) {
				$passFail = $1; $date = $2; }
			if ($passFail =~ /pass|fail|\d+/i) { 
				my $tmp = $listHistory{$key};	# remove the unreasable error - concat undefined variables
				if ($tmp) {;} else { $tmp="";}
				$listHistory{$key} = $tmp."$passFail\t"; 
				$isPassFail = 'y';
			} else {$isPassFail = 'n'; }
			if (($isPassFail =~ /y/i) && ($tcExecDateTimeCtr == 1)) { push (@tcExecDateTime, $date) ;} 
;
			}
		} elsif ($_ =~ /tcRunResult/i) {
			my $passFail = ""; my $date = "";
			if ($_ =~ /tcRunResult\s*(\S+)\s+\@\s+(\d\d\d\d-\d\d-\d\d\s+\d\d:\d\d:\d\d)/) {
			$passFail = $1; $date = $2; }
			if ($passFail =~ /pass|fail|\d+/i) { 
				my $tmp = $listHistory{$key};	# remove the unreasable error - concat undefined variables
				if ($tmp) {;} else { $tmp="";}
				$listHistory{$key} = $tmp."$passFail\t"; 
				$isPassFail = 'y';
			} else {$isPassFail = 'n'; }
			if (($isPassFail =~ /y/i) && ($tcExecDateTimeCtr == 1)) { push (@tcExecDateTime, $date) ;} 
		} else {
			;
		}
	} 
	close Fin;
	} else { print "Info: $SvrDrive/$SvrProjName/_list_history_tcRunResult.txt doesn't exist. Proceed ... (generateExcelReport won't work. Run propertyOp=list_history_tcRunResult)\n"; return 0 ;}

open Fout, "> $SvrDrive/$SvrProjName/_generateExcelReport.txt";
open Fout1, "> $SvrDrive/$SvrProjName/_generateExcelReport.html"; print Fout1 "<html><body><pre>\n";
my $currentDate ="";
for (my $i = 0; $i <= $#tcExecDateTime; $i++) { 
	$tcExecDateTime[$i] =~ /(\d\d\d\d-\d\d-\d\d)\s+(\d\d:\d\d:\d\d)/; my $date = $1; my $time = $2;
	if ($currentDate eq $date) { $tcExecDateTime[$i] = $time; $columnWidth[$i+2] = length ($time); } elsif ($currentDate ne $date) { $currentDate = $date; $columnWidth[$i+2] = length ("$date $time"); }
} 

printf Fout "Test Suite Name: $AutomationtsName\n";
printf Fout1 "Test Suite Name: $AutomationtsName\n";
printf Fout "%-${tcIdMax}s\t%-${tcDescMax}s\t", "tcId", "Description"; for (my $i = 0; $i <= $#tcExecDateTime; $i++) { print Fout "($tcExecDateTime[$i])\t"; } print Fout "\n";
printf Fout1 "%-${tcIdMax}s %-${tcDescMax}s", "tcId", "Description"; for (my $i = 0; $i <= $#tcExecDateTime; $i++) { print Fout1 "($tcExecDateTime[$i])"; } print Fout1 "\n";


foreach my $each (sort keys %listHistory) { 
	my $each_ = $each; 
	# if ($each_ =~ /testcase(\d\d\d\d)/) { $each_  = $1;	$each_ =~ s/^\s*00//g; }
	printf Fout "%-$columnWidth[0]s\t%-$columnWidth[1]s\t", $each_, $tcDesc{$each};
	printf Fout1 "%-$columnWidth[0]s %-$columnWidth[1]s ", $each_, $tcDesc{$each};
	my @fields = split (/\t/, $listHistory{$each}); 
	for (my $i=0; $i <= $#fields; $i++) {
		my $tmp;
		if ($columnWidth[$i + 2]) {;} else { $columnWidth[$i+2] = 10;}
		$tmp = $columnWidth[$i + 2] + 1;
		if ($tmp) {;} else { $tmp = $excelReportColumnWidth;} 
		printf Fout "%-${tmp}s\t", $fields[$i];
		printf Fout1 "%-${tmp}s ", $fields[$i];
	}
	print Fout "\n";
	print Fout1 "\n";
}

close Fout;
print Fout1 "</pre></body></html>\n";
close Fout1;
#### uncomment for debugging    print " -> $SvrDrive/$SvrProjName/_generateExcelReport.html\n";

1;
}

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";
	my $ps1_args_ = $ps1_args;
	$ps1_args_ =~ s/\\/\//g;

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; 
	my $cmd = $SvrProjName; 
	if (-e $cmd) {;} else { mkdir $cmd; }
	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 _smoke_ _regression_
2. Test case description 2 for testing _smoketest__regressiontest_the function 2 --- Please modifybbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb _smoke_
3. Test case description 3 for testing _smoketest_the function 3 --- Please modifycddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd _regression_
4. Test case description 4 for testing _regressiontest_the function 4 --- Please modify _smoke_
5. Test case description 5 for testing _regressiontest_the function 5 --- Please modify
6. Test case description 6 for testing the function 6 --- Please modify
EOF
;
}

EOF_
	close Fout;
	print "\n[Warning] Creating Temporial testsuite hook --> [".$SvrProjName."/index.pl]\n"; ; 
	# print "\n[Warning] Creating Temporial testsuite hook --> [".$workingDir."/index.pl]\n"; ; 
#_testsuiteName_: $tsNameTmp
#_testdriverName_: $tsDriver

}

sub generatePowershell_ps1_template {
	# my $cmd = $workingDir; 
	my $cmd = $SvrProjName; 
	open Fout, "> $cmd/index.ps1";
	my $tsNameTmp =	&getRoot($cmd);
	my $tmpWorkingDir = $workingDir; $tmpWorkingDir =~ s/\\/\//g;
print Fout<<EOF_;

###########################
param([INT]\$index = "-1", \$buildpath="")

if(\$verbose -eq \$true) { cls }

\$subHtml = "/auto_html/LBP_automation.html"
\$index = \$index -1 		
######################################################################################
# Dictionary for pre-canned test scenarios.
######################################################################################
\$testDictionary = \@()

\$testDictionary += \@( `
		\@{	"desc" = "Testcase1 description $tmpWorkingDir "; 
			"result" = "PASS";
		} `
)
\$testDictionary += \@( `
		\@{	"desc" = "Testcase2 description $tmpWorkingDir _smoketest_ _regression_ _regressiontest_"; 
			"result" = "FAIL"; 
		} `
)
\$testDictionary += \@( `
		\@{	"desc" = "Testcase3 Description $tmpWorkingDir _smoketest_ _regression"; 
			"result" = "FAIL"; `
		} `
)
\$testDictionary += \@( `
		\@{	"desc" = "Testcase4 Description $tmpWorkingDir _smoketest_"; `
			"result" = "PASS"; `
		} `
)


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

\$idx = [Int32]::Parse(\$index)
\$testDictionaryCount =  \$testDictionary.length - 1
\$count = 1
if((\$idx -lt 0) -or (\$idx -gt \$testDictionaryCount)) 
{
	foreach(\$dictionaryDesc in \$testDictionary) 
	{
		Write-Host "\$count :"\$dictionaryDesc.desc
		\$count++
	}
	exit
}

write-host \$testDictionary[\$idx].result;



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

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

#_testsuiteName_: $tsNameTmp
#_testdriverName_: $tsDriver

}

sub generateTAFTestsuite {goto &generateTestsuite}
sub generateTestsuite { 						# Generating 1. index.pl 2. index.pl + index_pyAnvil.pl 
	my $cmd = $SvrProjName ;  $cmd = shift if @_;
	if ($cmd !~ /:/) { $cmd = $c.'/'.$_TAF.'/'.$cmd; }
	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 ($ps1_args =~ /^\s*$/) { $ps1_args = "-ps1_args powershell_args";}
 	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; $ps1_args_ =~ s/\\/\//g; # ps1_args 
			my $cmd = sprintf "ps1_args=$ps1_args_;testsuite=$testsuiteName;create=testcase%04d/customTC:${testDriverName}_space_${tcCtr}:customTC\n", $tcCtr  ; 
			&processTCs("",$cmd);
			my $tcnameTmp = sprintf "$c/$_TAF/$testsuiteName/testcase%04d", $tcCtr++;
			my $propertyTmp = $each;
			$propertyTmp =~ s/ /_space_/g; 
			$propertyTmp =~ s/:/_column_/g; 
			$propertyTmp =~ s/=/_eq_/g; 
			$propertyTmp =~ s/ /__/g; 
			&processProperty("",$tcnameTmp, "add=tcDesc:$propertyTmp");
			foreach $each (split (",", $tags)) {
				if ($propertyTmp =~ /$each/i) { &processProperty("",$tcnameTmp, "add=$each:y"); }
			}
		}
	}
	$tcCtr = 1;
	############ 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.pl\n";


	# if ( -e "$c/$testsuiteName/_tcMap.txt" ) { open Fout3, ">$c/$_TAF/$testsuiteName/_tsProperty.txt"; print Fout3 "Hello world\n"; close Fout3; }

	if ( -e "$c/$testsuiteName/_tcMap.txt" ) { 
		open Fin2, "$c/$testsuiteName/_tcMap.txt" ;
		open Fout2, ">$c/$_TAF/$testsuiteName/_tcMap.txt"; 
		while ($_=<Fin2>) { $_ =~ s/$c/$c\/$_TAF/ig; print Fout2 $_; }
		close Fout2; 
		close Fin2;
		print    "  -->$c/$_TAF/$testsuiteName/_tcMap.txt\n";
	}
	$testsuiteName = $testsuiteName;
			#$cmd = sprintf "tcDelay=0;testcaseNode=$testcaseNode;testsuite=$testsuiteName;list"; 
			# &processTCs("",$cmd);
			$cmd = sprintf "$c/$_TAF/taf.pl tcDelay=0;testcaseNode=$testcaseNode;testsuite=$testsuiteName;list"; 
			print "\n\nlist: todo>". `$cmd`;
			&generateRootIndex();
	if ($interact =~ /\by\b/) {system ("C:/Program Files/Internet Explorer/iexplore.exe", "$c/$_TAF/$testsuiteName/index.htm");}

	print "\n";
	1;
}


sub generateTAFChildTestsuites { 						# Generating 1. index.pl 2. index.pl + index_pyAnvil.pl 
	my $cmd = $SvrProjName ;  $cmd = shift if @_;
	if ($cmd !~ /:/) { $cmd = $c.'/'.$_TAF.'/'.$cmd; }
	my $cwd = $cmd; my $testsuiteName = &getRoot_4($cwd);  			############ $testsuiteName = &getRoot(&getcwd());  
	if (-e "$cmd\/index.ps1") { $cmd = $cmd . "\/index.ps1";	#### pre-existing testsuiteHook is index.ps1 
		}
	elsif (-e "$cmd\/index.pl")     { 
		$cmd = $cmd . "\/index.pl";}				#### pre-existing testsuiteHook is index.pl 
	else  { 							####  No pre-existing index.pl 
		print "generateChildTestsuites: The parentTestsuite doesn't exist! \n"; exit; 
	}								

	open FOUT, ">$c/$_TAF/_generateChildTestsuite.bat"; 

 	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+)
		 $each = " _full_ ".$each;
		@_ = $each =~ /_(\w+)_/g; 
		if ($#_ > 0) {	
			foreach my $each1 (@_) { 
				if ($recordTags{$each1}) { $recordTags{$each1} = $recordTags{$each1} + 1; } else { $recordTags{$each1} = 1;}
			} 
		}
	}

		$cmd = "$c/$_TAF/$taf testsuite=$SvrProjName;tcPropertyName=_full_;generateTestsuiteByDesc\n"; $cmd =~ s/\//\\/g; print FOUT "$cmd";
		$cmd = "$c/$_TAF/$taf testsuite=$SvrProjName/_full_;generateTestsuite\n"; $cmd =~ s/\//\\/g; print FOUT "$cmd";
		
	foreach my $key (sort hashValueDescendingNum (keys(%recordTags))) { 
		if ($key !~ /\bfull\b/i) {
			# print FOUT "$recordTags{$key} $key\n"; 
		$cmd = "$c/$_TAF/$taf testsuite=$SvrProjName;tcPropertyName=_${key}_;generateTestsuiteByDesc\n"; $cmd =~ s/\//\\/g; print FOUT "$cmd";
		$cmd = "$c/$_TAF/$taf testsuite=$SvrProjName/_${key}_;generateTestsuite\n"; $cmd =~ s/\//\\/g; print FOUT "$cmd";
		}
	
	}
	close FOUT;
	print " -> $c/$_TAF/_generateChildTestsuite.bat\n --.....-> Running $c/$_TAF/_generateChildTestsuite.bat to generate _smoke_, _regression_ sub Testsuite\n";    
	# my $rst = `$c/$_TAF/_generateChildTestsuite.bat`; 
	
	##############################################################################################

	1;
}
sub hashValueDescendingNum { $recordTags{$a} <=> $recordTags{$b}; }


sub help4install {
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.

        ---------------------------------------------------------------------------------------------------------------
	$c/$_TAF/index.htm	         WebAccess TAF-Testbed
	$c/$_TAF/taf.pl -help4intro      TAF Introduction
	$c/$_TAF/taf.pl -help4install    Command_line usages 
	$c/$_TAF/taf.pl -help4cmd        Command_line usages 
	$c/$_TAF/taf.pl -help4developer  Historical and under-development Functions
        ---------------------------------------------------------------------------------------------------------------

	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)
-----------------------------------------------------------------------------------------------------------------------
EOF
	print $help;
	&genDriver();
	1;
}

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

	$c/$_TAF/taf.pl helpmore                TAF Usage Samples
	$c/$_TAF/taf.pl testsuite=_testsuit3_   Frequently Used Command line


	$c/$_TAF/index.htm	       WebAccess TAF-Testbed
	$c/$_TAF/taf.pl help4intro      TAF Introduction
	$c/$_TAF/taf.pl help4install    Command_line usages 
	$c/$_TAF/taf.pl help4cmd        Command_line usages 
	$c/$_TAF/taf.pl help4dev        Historical and under-development Functions

-----------------------------------------------------------------------------------------------------------------------
EOF
	print $help;
	&genDriver();
	1;
}


sub help4intro {
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)
-----------------------------------------------------------------------------------------------------------------------
EOF
	print $help;
	&genDriver();
}

sub helpmore {
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 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
		
	#####################  Powershell Testsuite Exmaples     ##################################
	$c\\$_TAF\\taf.pl -processTSs create=c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_ps1__powershell_
	$c\\$_TAF\\generatePyAnvilTestsuite.pl -buildpath c:/_CRB_/AppBuildpath -genTAF y

	#####################  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]		
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;tppp1=;tppn1=;tppp2=;tppn2=....

	$c\\$_TAF\\taf.pl tcPropertyName=smoke;tsFilterDefault=c:\\_CRB_\\AppBuildpath;generateTestsuiteByDesc
	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();
	1;
}

sub help4cmd{
if ( $^O =~ /MSWin32/ ) {; } else { print "TAF supports Win32 ONLY now.\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.

	[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
		Copy Testsuite 
			taf.pl tsFrom=e.txt;tsTo=ee.txt;copyTS
			
		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 -help 
	$c\\$_TAF\\taf.pl genDriver
	$c\\$_TAF\\taf.pl generateIndex_pl | generateIndex_pyAnvil_pl
	$c\\$_TAF\\taf.pl generateTestsuite
	$c\\$_TAF\\taf.pl generateRootIndex
	taf.pl testsuite=_testsuite1_;resetTSFileName=_list_history_tcRunResult.txt;resetTSFile;resetTSFile


	#####################  TS/TC Management (Create/List/Exec) ##################################
		
	$c\\$_TAF\\taf.pl -processTCs create=tc1/fail,overwrite
	$c\\$_TAF\\taf.pl -processTSs [create|delete|add]=$c/_testsuite1/_testsuite2
	$c\\$_TAF\\taf.pl [SUTSymbol|tsFilterDefault]=_;tsFilter="2.2.0.217[_doit_];scanTestsuites 
	$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 testsuit=CPD_QA_Tests/BATtests/MVTests/Bat/MV_2-0-1-0057/_MV_SDK_OCSP;list
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;performanceMode=fast;list
	$c\\$_TAF\\taf.pl -processTCS tsDriver=index_pyAnvil.pl;printVars;testsuite=_testsuite3_;list
	$c\\$_TAF\\taf.pl tcPropertyPatternPattern=\\d+_pipe_null;tcPropertyPatternName=tcRunResult;testsuite=_testsuite3_  rem list tcRunResult =~ /performance|null/
	$c\\$_TAF\\taf.pl tcPropertyPatternPattern=fail;tcPropertyPatternName=tcRunResult;testsuite=_testsuite3_

	$c\\$_TAF\\taf.pl tcIdMin=5;printVars;testsuite=_testsuite3_;exec
	$c\\$_TAF\\taf.pl ExecutionType=[runTC|runTS]
	$c\\$_TAF\\taf.pl exitTAF
	$c\\$_TAF\\taf.pl Execution_24_7=y;NofExecution=5;Execution=24hour;testsuite=_MV_SDK_OCSP;[list|exec]

	#####################  Powershell Testsuite Exmaples     ##################################
	$c\\$_TAF\\taf.pl -processTSs create=c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_ps1__powershell_
	$c\\$_TAF\\generatePyAnvilTestsuite.pl -buildpath c:/_CRB_/AppBuildpath -genTAF y

	#####################  get/set/list/list_history 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]

        $c\\$_TAF\\taf.pl testsuite=Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\AutomationtsNameSUT\\_full_;AutomationtsName=AutomationtsNameSUT;propertyOp=list_tcDesc 
        $c\\$_TAF\\taf.pl testsuite=Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\AutomationtsNameSUT\\_full_;AutomationtsName=AutomationtsNameSUT;propertyOp=list_history_tcRunResult
        $c\\$_TAF\\taf.pl testsuite=Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\AutomationtsNameSUT\\_full_;AutomationtsName=AutomationtsNameSUT;generateExcelReport

	##################### 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]		
	$c\\$_TAF\\taf.pl testsuite=_testsuite2_;pm=fast;tppp1=;tppn1=;tppp2=;tppn2=....

	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();
	1;
}


sub help4dev{
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 testsuite=Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\Automation_MVSDK\\_full_;propertyOp=list_tcDesc
taf.pl testsuite=Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\Automation_MVSDK\\_full_;listHistory
taf.pl testsuite=generateReport

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_
	$c\\$_TAF\\taf.pl testsuite=_testsuite1_;resetTSFileName=_list_history_tcRunResult.txt;resetTSFile;resetTSFile

	########################## 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;
	1;
}
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";
	}
	1;
}
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  "$c/$_TAF";

	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 TC/TS under c:\\$_TAF -----------------------------------
REM * Create Functional test case, which returns Pass with different execution time. 
REM * Create Functional test case, which returns Fail with different execution time. 
REM * Create Performance test case, which returns number of seconds
REM * Create Functional test case, with logs and links in the logs (_tcLogAppend.txt)
REM * Create Functional test case, with expected failure (expF)
REM * Test case execution  testcase=string : (testType=tc or ts: what does it mean?) 
REM * Test case execution  testcase=regExp : (testType=tc or ts: what does it mean?) 
REM * Test suite execution  testsuite=string : (testType=tc or ts: what does it mean?) 
REM * Test suite execution  testsuite=regExp : (testType=tc or ts: what does it mean?) 
REM * Test case status : moving ">"
REM * Test case 24/7 execution
REM * Test suite 24/7 execution
REM * Test case "stop" 
REM * Test suite "stop"
REM * Test suite title tsProperty.txt
REM * Test case  title tcProperty.txt
REM create test_suite (_test_suite?_)/_test_case?_  under c:\\$_TAF
REM * Modify 
REM * Delete TC/TS
REM * Update TS/TC Status
REM ------------- Create TC/TS under $c\\$_TAF -----------------------------------

$c\\$_TAF\\taf.pl testsuite=_testsuite1_;create=testcase0001/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;create=testcase0002/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;create=testcase0003/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;create=testcase0004/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;create=testcase0005/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;create=testcase0006/overwrite,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;create=testcase0001/overwrite,sleep=20
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;create=testcase0002/overwrite,sleep=20
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;create=testcase0003/overwrite,sleep=40
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;create=testcase0004/overwrite,sleep=30
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;create=testcase0005/overwrite,sleep=20
$c\\$_TAF\\taf.pl testsuite=_testsuite2_;create=testcase0006/overwrite,sleep=20
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0001/overwrite,sleep=2
REM create performance test 
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0002/overwrite,perf,sleep=3
REM create Failed Functional test 
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0003/overwrite,fail,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0004/overwrite,sleep=2
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0005/overwrite,fail,sleep=4
REM create functional test /w log
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0006/overwrite,genLog,sleep=10
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0007/overwrite,fail,genLog,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0008/overwrite,pass,genLog,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0009/overwrite,expectedFail,genLog,sleep=1
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;create=testcase0010/overwrite,expF,genLog,sleep=1

REM create customrized TAF test cases for property operation test (TC contents are hardcoded in TAF)
$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 exec all test_suite (testsuite!= Regexp; testcase=RegExp)

$c\\$_TAF\\taf.pl testsuite=_testsuite1_;testType=tc;exec
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;testType=tc;testcase=.*;exec
$c\\$_TAF\\taf.pl testsuite=_testsuite1_;testType=tc;testcase=testcase.1*;exec

$c\\$_TAF\\taf.pl testsuite=_testsuite2_;testType=tc;exec
$c\\$_TAF\\taf.pl testsuite=_testsuite3_;testType=tc;exec

REM test execution status (1. moving symbol = test-in-prog 2. Current execution status = getWeb_ 3. delete TS
$c\\$_TAF\\taf.pl testsuit=_testsuite1_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite2_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite4_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;updateWeb_=_testcase1_/2
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;updateWeb_=_testcase2_/1
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;updateWeb_=_testcase3_/3
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;getWeb_=_testcase1_
$c\\$_TAF\\taf.pl testType=tc;delete=c:/_TAF/_test_suit1_
REM TS Property update 
REM *Verification* _test_suit1_ is removed from disk and webUI
REM
REM ------------- Create TC/TS under c:\\$_TAF -----------------------------------
   

REM ------------- Create TC/TS outside c:_testsuite5_ .... ---------------------
REM generate test suite from TS Hook (index.pl) - Will be batched by scanTestsuite
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite1_/_TS1;createTS
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite2_/_TS1;createTS
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite3_/_TS1;createTS
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite4_/_TS1;createTS

$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite1_/_TS1;generateTAFTestsuite 
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite2_/_TS1;generateTAFTestsuite 
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite3_/_TS1;generateTAFTestsuite 
$c\\$_TAF\\taf.pl testsuite=c:/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite4_/_TS1;generateTAFTestsuite 

REM *Verification* TC_TAF c:/_TAF/_TAF/_testsuiteTestBed/_testsuite?_ should be created
$c\\$_TAF\\taf.pl testsuite=_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite1_/_TS1;exec
$c\\$_TAF\\taf.pl testsuite=_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite2_/_TS1;exec
$c\\$_TAF\\taf.pl testsuite=_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite3_/_TS1;exec
$c\\$_TAF\\taf.pl testsuite=_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite4_/_TS1;exec

REM ------------- Create TC/TS outside c:_testsuite5_ .... ---------------------


REM ------------- Create Perl-Testsuite Hook and its Test suites /w Tag-based sub-Testsuites (_smoketest_, _regression_ )

$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl;createTS
$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl;createTS
$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites3_/_testsuite_pl;createTS
$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites4_/_testsuite_pl;createTS

$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl;generateTAFTestsuite
$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl;generateTAFTestsuite
$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites3_/_testsuite_pl;generateTAFTestsuite
$c\\$_TAF\\taf.pl testsuite=c:/_perlTestsuite_/AppBuildpath/_automated_testsuites4_/_testsuite_pl;generateTAFTestsuite

REM generate tcDesc-Tag (_smoketest_, _regression_) test suite. There is no TAG in the hook. (The following will break TAF)
Rem $c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl;generatePropertyTestsuite
Rem $c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl;generatePropertyTestsuite
Rem $c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl;generatePropertyTestsuite


$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl;generatePropertyTestsuite

$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites2_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites2_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites2_\\_testsuite_pl;generatePropertyTestsuite

$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites3_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites3_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites3_\\_testsuite_pl;generatePropertyTestsuite

$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites4_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites4_\\_testsuite_pl;generatePropertyTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites4_\\_testsuite_pl;generatePropertyTestsuite


$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl\\_full_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl\\_smoketest_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites1_\\_testsuite_pl\\_regressiontest_;generateTAFTestsuite

$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites2_\\_testsuite_pl\\_full_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites2_\\_testsuite_pl\\_smoketest_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites2_\\_testsuite_pl\\_regressiontest_;generateTAFTestsuite

$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites3_\\_testsuite_pl\\_full_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites3_\\_testsuite_pl\\_smoketest_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites3_\\_testsuite_pl\\_regressiontest_;generateTAFTestsuite

$c\\$_TAF\\taf.pl tcPropertyName=_full_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites4_\\_testsuite_pl\\_full_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_smoketest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites4_\\_testsuite_pl\\_smoketest_;generateTAFTestsuite
$c\\$_TAF\\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\\_perlTestsuite_\\AppBuildpath\\_automated_testsuites4_\\_testsuite_pl\\_regressiontest_;generateTAFTestsuite


REM ------------- Create Perl-Testsuite Hook and its Test suites /w Tag-based sub-Testsuites (_smoketest_, _regression_ )
REM                  (make sure the ts ends with _powershell_, which indicate a powershell testsuite)


REM ------------- Create Powershell-Testsuite Hook and its Test suites    -  Generate Tag-based sub-Testsuites -------------
$c\\$_TAF\\taf.pl testsuite=c:/_powershellTestsuite_/AppBuildpath/_automated_testsuites_/_testsuite_ps1__powershell_;createTS

$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_full_;testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_smoketest_;testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_regressiontest_;testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_;generatePropertyTestsuite

$c\\$_TAF\\taf.pl testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_;generateTAFTestsuite
$c\\$_TAF\\taf.pl testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_\\_full_;generateTAFTestsuite
$c\\$_TAF\\taf.pl testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_\\_smoketest_;generateTAFTestsuite
$c\\$_TAF\\taf.pl testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_\\_regressiontest_;generateTAFTestsuite
$c\\$_TAF\\taf.pl testsuite=c:\\_powershellTestsuite_\\AppBuildpath\\_automated_testsuites_\\_testsuite_ps1_;generateTAFTestsuite		REM combine all the property testsuites
REM ------------- Create Powershell-Testsuite Hook and its Test suites    -  Generate Tag-based sub-Testsuites -------------

REM Demo for generating daily excel report 

REM ------------- Scabiality Test: multi-testsuites and testing scanTestsuite  --------------------------
REM
REM helloworld-testbed powershell-Hook (property = _full_, _smoketest_, _regressiontest_)
$c\\$_TAF\\taf.pl testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite1__powershell_;createTS
$c\\$_TAF\\taf.pl testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite2__powershell_;createTS
$c\\$_TAF\\taf.pl testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite3__powershell_;createTS
$c\\$_TAF\\taf.pl testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite4__powershell_;createTS

$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_full_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite1_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_smoketest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite1_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_regressiontest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite1_;generatePropertyTestsuite

$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_full_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite2_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_smoketest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite2_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_regressiontest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite2_;generatePropertyTestsuite

$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_full_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite3_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_smoketest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite3_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_regressiontest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite3_;generatePropertyTestsuite

$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_full_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite4_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_smoketest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite4_;generatePropertyTestsuite
$c\\$_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_regressiontest_;testsuite=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite4_;generatePropertyTestsuite


REM scanTestsuites from testsuite directory  (recursive execution should only be executed once)
$c\\$_TAF\\taf.pl testsuite=c:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite1__doit_;scanTestsuites
$c\\$_TAF\\taf.pl testsuite=c:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite2__doit_;scanTestsuites
$c\\$_TAF\\taf.pl testsuite=c:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite3__doit_;scanTestsuites
$c\\$_TAF\\taf.pl testsuite=c:\\Autobat\\Bat\\QA_Tests\\BATtests\\BAT\\Automation_testsuite4__doit_;scanTestsuites

REM ------------- Scabiality Test: multi-testsuites and testing scanTestsuite  --------------------------


REM Solution: testcaseNode=testcase will enforce only one level of scan is achieved (no different levels of scan combined)

REM update testbed' s _thProperties.txt[s]. This should be a smart-build function. Run this before running taf.pl list
$c\\$_TAF\\taf.pl printTestBedProperties;generateRootIndex 


$c\\$_TAF\\taf.pl testsuit=_testsuite1_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite2_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite4_;testType=tc;list
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;updateWeb_=testcase0001/2
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;updateWeb_=testcase0002/1
$c\\$_TAF\\taf.pl testsuit=_testsuite3_;testType=tc;updateWeb_=testcase0003/3


rem Mark TS with comments
rem taf.pl testsuite=_testsuite1_;tcComment2=abcd;mark 
\@start "" /b "C:\\Program Files\\Internet Explorer\\iexplore.exe" "C:\\$_TAF\\_testsuite3_\\index.htm"

# mark3
rem todo: --------------------- property operation and property filter
rem add/set, createTemplate, del, modify, match/filter, get/list (values,_all_, history, latest, last, value, filters), 
REM Property Operation: add a property
REM Property Operation: set/modify a property
REM Property Operation: get/list a property
REM Property Operation: print TC properties
REM Property Operation: propertyFilter 
REM 
REM	copy testsuites			taf.pl tsFrom=e.txt;tsTo=ee.txt;copyTS   

REM Test the tcFilter functions
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=set_property1_eq_value1a_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=set_property1_eq_value1b_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=set_property1_eq_value1c_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=set_property1_eq_value1d_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=set_property1_eq_value1e_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=set_property1_eq_value1f_doit_

c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0002;propertyOp=set_property1_eq_value1a_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0002;propertyOp=set_property1_eq_value1b_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0002;propertyOp=set_property1_eq_value1c_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0002;propertyOp=set_property1_eq_value1d_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0002;propertyOp=set_property1_eq_value1e_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0002;propertyOp=set_property1_eq_value1f_doit_

REM get TC properties 
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=get_property1
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=get_history_property1
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=get_last_property1
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=get_latest_property1

REM del TC properties (remove all the property-values)
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=set_property2_eq_value2a_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=del_property2_doit_

REM Modify TC properties (same as add properties - append to thProperty.txt)
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=modify_property3_eq_value3f_doit_

REM print TS/TC tcFilters 
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;printTCFilters		
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;printTCFilters

REM property match (might need regExp in the future)

c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=match_property2_as_value1h_doit_
c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase0001;propertyOp=match_property1_as_value1h_doit_

c:\\$_TAF\\taf.pl testsuite=_testsuite3_;printTCFilters
rem *Technology Reserve* c:\\$_TAF\\taf.pl testsuite=_testsuite3_;propertyOp=set_propverty1_as_value1_doit_
rem *Technology Reserve* c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase2;propertyOp=set_property1_as_value2_doit_
rem *Technology Reserve* c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase2;printTCFilters

rem *Technology Reserve* c:\\$_TAF\\taf.pl testsuite=_testsuite3_;printTcFilters
rem *Technology Reserve* c:\\$_TAF\\taf.pl testsuite=_testsuite3_;propertyOp=get_property1
rem *Technology Reserve* c:\\$_TAF\\taf.pl testsuite=_testsuite3_;testcase=testcase2 propertyOp=get_property1

REM Old memories 
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'

EOF
	open Fout, "> $c/$_TAF/taf.txt"; print Fout $str; close Fout; print " --> $c/$_TAF/taf.txt\n"; my $cmd = "$c/$_TAF/taf.txt"; 
	open Fout, "> $c/$_TAF/taf.bat"; print Fout $str; close Fout; print " --> $c/$_TAF/taf.bat\n";    $cmd = "$c/$_TAF/taf.bat"; 
	if ( &enterY("Execute $c\\taf.bat (y/n)? ") =~ /y/) {	system $cmd; }
	}
	1;
}

sub enterY { print shift ; while($_ = <STDIN>) { if (($_ =~ /n/i) || ($_ =~ /^\s*$/)) { return "n"; } if ($_ =~ /y/i) { return "y"; }} }
# install is replaced by genDriver () . it is kept for backwards compatible
sub install 		{ &genDriver(); 1; }


sub printTestBedProperties {

	############ Generate taf Property file for _testsuite1_
open Fout, ">$c/$_TAF/_testsuite1_/tsProperty.txt";
my $str = <<EOF;
There is no tsProperty.txt for c:\\_TAF\\_testsuite1_. This is as designed.
EOF
print Fout $str;
close Fout; 
	############ Generate taf Property file for _testsuite1_

	############ Generate taf Property file for _testsuite2_
open Fout, ">$c/$_TAF/_testsuite2_/tsProperty.txt";
$str = <<EOF;
There is no tsProperty.txt for c:\\_TAF\\_testsuite2_. This is as designed.
EOF
print Fout $str;
close Fout; 
	############ Generate taf Property file for _testsuite2_



	############ Generate taf Property file for _testsuite3_
open Fout, ">$c/$_TAF/_testsuite3_/tsProperty.txt";
$str = <<EOF;
web_ui_title: Test Automation Framework : web_ui_title
$c/$_TAF/_testsuite3_/testcase0001| 1  Test case 1 description                            Manual edit please     
$c/$_TAF/_testsuite3_/testcase0002| 2  Test case 2 Perform TC  for tsProperty.txt         Manual edit please     
$c/$_TAF/_testsuite3_/testcase0003| 3  Test case 3 Fail TC     for .. tsProperty.txt      Manual edit please     
$c/$_TAF/_testsuite3_/testcase0004| 4  Test case 4 Pass TC     for ... tsProperty.txt     Manual edit please     
$c/$_TAF/_testsuite3_/testcase0005| 5  Test case 5 Fail TC     for .... tsProperty.txt    Manual edit please     
$c/$_TAF/_testsuite3_/testcase0006| 6  Test case 6 TC /w Log   for ..... tsProperty.txt   Manual edit please     
$c/$_TAF/_testsuite3_/testcase0007| 7  Test case 7 _Expected_Fail_ for ... tsProperty.txt Manual edit please     
$c/$_TAF/_testsuite3_/testcase0008| 8  Test case 8 _Expected_Fail_ for ... tsProperty.txt Manual edit please     
$c/$_TAF/_testsuite3_/testcase0009| 9  Test case return Expected_f_a_i_l   for ... tsPro  Manual edit please     
$c/$_TAF/_testsuite3_/testcase0010| 10 Test case return expF               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_|001  TAF Testbed 1 : Test Case  Management: TC list, TC execution, TC Reporting /o TC Description
$c/$_TAF/_testsuite2_|002  TAF Testbed 2 : Test Case  Management: TC list, TC execution, TC Reporting /o TC Description 
$c/$_TAF/_testsuite3_|003  TAF Testbed 3 : Test Case  Management: Concurrency, Performance TCs, TC Logging, TC Description 
$c/$_TAF/_testsuite4_|004  TAF Testbed 4 : Test Case  Management: Property operations : add/get properties 

$c/$_TAF/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite1_/_TS1|007  TAF Testbed 7 : Test Suite Management: Multiple test suite coexistence (testsuite1)
$c/$_TAF/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite2_/_TS1|008  TAF Testbed 8 : Test Suite Management: Multiple test suite coexistence (testsuite2)
$c/$_TAF/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite3_/_TS1|009  TAF Testbed 9 : Test Suite Management: Multiple test suite coexistence (testsuite3)
$c/$_TAF/_testsuite5_non_TAF_/_testsuiteTestBed/_testsuite4_/_TS1|010  TAF Testbed 10: Test Suite Management: Multiple test suite coexistence (testsuite4)

$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl|011  TAF Testbed 11: ts1: perl testsuite hook /o tags _smoketest_, _regressiontest_
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl|012  TAF Testbed 12: ts2: perl testsuite hook /o tags _smoketest_, _regressiontest_
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites3_/_testsuite_pl|013  TAF Testbed 13: ts3: perl testsuite hook /o tags _smoketest_, _regressiontest_
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites4_/_testsuite_pl|014  TAF Testbed 14: ts4: perl testsuite hook /o tags _smoketest_, _regressiontest_

$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl|015  TAF Testbed 15: Test Suite Management: Perl Script Automation    Test Suite 1 (_full_, _smoketest_, _regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl/_full_|016  TAF Testbed 16: Test Suite Management:                       sub Test Suite   (_full_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl/_regressiontest_|017  TAF Testbed 17: Test Suite Management:                       sub Test Suite   (_regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites1_/_testsuite_pl/_smoketest_|018  TAF Testbed 18: Test Suite Management:                       sub Test Suite   (_smoketest_)


$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl|019  TAF Testbed 19: Test Suite Management: Perl Script Automation    Test Suite 2 (_full_, _smoketest_, _regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl/_full_|020  TAF Testbed 20: Test Suite Management:                       sub Test Suite   (_full_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl/_regressiontest_|021  TAF Testbed 21: Test Suite Management:                       sub Test Suite   (_regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites2_/_testsuite_pl/_smoketest_|022  TAF Testbed 22: Test Suite Management:                       sub Test Suite   (_smoketest_)


$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites3_/_testsuite_pl|023  TAF Testbed 23: Test Suite Management: Perl Script Automation    Test Suite 3 (_full_, _smoketest_, _regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites3_/_testsuite_pl/_full_|024  TAF Testbed 24: Test Suite Management:                       sub Test Suite   (_full_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites3_/_testsuite_pl/_regressiontest_|025  TAF Testbed 25: Test Suite Management:                       sub Test Suite   (_regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites3_/_testsuite_pl/_smoketest_|026  TAF Testbed 26: Test Suite Management:                       sub Test Suite   (_smoketest_)


$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites4_/_testsuite_pl|027  TAF Testbed 27: Test Suite Management: Perl Script Automation    Test Suite 4 (_full_, _smoketest_, _regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites4_/_testsuite_pl/_full_|028  TAF Testbed 28: Test Suite Management:                       sub Test Suite   (_full_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites4_/_testsuite_pl/_regressiontest_|029  TAF Testbed 29: Test Suite Management:                       sub Test Suite   (_regressiontest_)
$c/$_TAF/_perlTestsuite_/AppBuildpath/_automated_testsuites4_/_testsuite_pl/_smoketest_|030  TAF Testbed 30: Test Suite Management:                       sub Test Suite   (_smoketest_)


$c/$_TAF/_powershellTestsuite_/AppBuildpath/_automated_testsuites_/_testsuite_ps1_|031  TAF Testbed 31: Test Suite Management: Powershell Script Automation Test Suite(_full_, _smoketest_, _regressiontest_)
$c/$_TAF/_powershellTestsuite_/AppBuildpath/_automated_testsuites_/_testsuite_ps1_/_full_|032  TAF Testbed 32: Test Suite Management:                                        (_full_)
$c/$_TAF/_powershellTestsuite_/AppBuildpath/_automated_testsuites_/_testsuite_ps1_/_smoketest_|033  TAF Testbed 33: Test Suite Management:                                        (_smoketest_)
$c/$_TAF/_powershellTestsuite_/AppBuildpath/_automated_testsuites_/_testsuite_ps1_/_regressiontest_|034  TAF Testbed 34: Test Suite Management:                                        (_regressiontest_) 

$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite1_|035  TAF Testbed 35: Test suite Tree structure: Test suite Node (in develop)  of testsuite1
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite1_/_full_|036  TAF Testbed 36: Test Suite Management: Test Suite Hook (testsuite1/index.ps1) (_full_, _smoketest_, _regressiontest_) 
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite1_/_regressiontest_|037  TAF Testbed 37: Test Suite Management:                                        (_regression tests_)
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite1_/_smoketest_|038  TAF Testbed 38: Test Suite Management:                                        (_smoketest_)

$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite2_|039  TAF Testbed 39: Test suite Tree structure: Test suite Node (in develop)  of testsuite1
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite2_/_full_|040  TAF Testbed 40: Test Suite Management: Test Suite Hook (testsuite2/index.ps1) (_full_, _smoketest_, _regressiontest_) 
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite2_/_regressiontest_|041  TAF Testbed 41: Test Suite Management:                                        (_regression tests_)
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite2_/_smoketest_|042  TAF Testbed 42: Test Suite Management:                                        (_smoketest_)

$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite3_|043  TAF Testbed 43: Test suite Tree structure: Test suite Node (in develop)  of testsuite1
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite3_/_full_|044  TAF Testbed 44: Test Suite Management: Test Suite Hook (testsuite3/index.ps1) (_full_, _smoketest_, _regressiontest_) 
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite3_/_regressiontest_|045  TAF Testbed 45: Test Suite Management:                                        (_regression tests_)
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite3_/_smoketest_|046  TAF Testbed 46: Test Suite Management:                                        (_smoketest_)

$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite4_|047  TAF Testbed 47: Test suite Tree structure: Test suite Node (in develop)  of testsuite1
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite4_/_full_|048  TAF Testbed 48: Test Suite Management: Test Suite Hook (testsuite4/index.ps1) (_full_, _smoketest_, _regressiontest_) 
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite4_/_regressiontest_|049  TAF Testbed 49: Test Suite Management:                                        (_regression tests_)
$c/$_TAF/Autobat/Bat/QA_Tests/BATtests/BAT/Automation_testsuite4_/_smoketest_|050  TAF Testbed 50: Test Suite Management:                                        (_smoketest_)


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;
}


sub sortCmdLog {
my %record;
open Fin, "$c/$_TAF/_cmdLogs.txt"; 
while (<Fin>) { if ($_ =~ /(.+)>\s+/) { if ( &Date_Cmp (&DateCalc("now", "+0 day"), &DateCalc("now", $commandLogLifeSpan))  >= 0  ) {$record{$1} = $_;} } } close Fin;
open Fout, "> $c/$_TAF/_cmdLogs.txt_"; foreach my $each (reverse sort keys %record) { $record{$each} =~ s/\s*\n$//g; if ($record{$each}) {print Fout "$record{$each}\n";} } close Fout;
copy ("$c/$_TAF/_cmdLogs.txt_", "$c/$_TAF/_cmdLogs.txt");
}

################################################################################
#	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;
}

sub appendtoFileStart() {  	# TH:Generic Functions: append to file (TH:Generic Functions)
    my $fname = $_[0];
    if (-e $fname ) { open Fin, $fname; @_=<Fin>; close Fin;}
    open Fout, ">>$fname";
    print Fout "$_[1]\n";
    print Fout @_;
    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>) { if ($_ =~ /exitTAFGracefullyString=(.+)\s*;\s*exitTAF/) { $record{$1} = $_; } } close Fin;
	if ( $content  =~ /exitTAFGracefullyString=(.+)\s*;\s*exitTAF/) {$record{$1} = $content;}
    open Fout, ">$fname_"; foreach my $each (sort keys %record) { print Fout $record{$each} } close Fout;
    move ($fname_, $fname);
}

sub appendtoFileUniqly { # 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; }
	if (-e $fname) {
     	open Fin ,  "$fname"; while ($_ = <Fin>) { $_ =~ s/\s*\n//g; $record{$_} = $_;  } close Fin; $record{$content}=$content;
     	open Fout, ">$fname_"; foreach my $each (sort keys %record) { print Fout "$record{$each}\n" if ($record{$each} !~ /^\s*$/); } 
	close Fout;
	move ($fname_, $fname);
     } else {
 	    open Fout , ">$fname" || die "Can't open $fname:$!";
 		print Fout $content;
 	    close  Fout;
     }
}

sub write2File{ # 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 Fout, ">$fname_"; print Fout $content; close Fout; move ($fname_, $fname);
}


sub copyFile { # fname, fileContent, maxTCExecTime 
     my $fnameFrom         = "e.txt"    ; $fnameFrom     = shift if @_; 
     my $fnameTo           = "e.txt"    ; $fnameTo     = 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; }
	copy ($fnameFrom, $fnameTo);
}

################################################################################
#	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 getExitTAFGracefullyLock  { 
	if ( -e $exitTAFGracefullyLock) { 
		open Fin, $exitTAFGracefullyLock || die "Can't open $exitTAFGracefullyLock:$!";
		$_ = <Fin>;
		close Fin;
		if ($_ =~ /exitTAFGracefullyString\s*=\s*(.+)/) {
		return $1;
		}
	} else { return "unlocked"; } 
}
sub detectExitTAFGracefullyLock  { if ( -e $exitTAFGracefullyLock) { return "locked"; } else { return "unlocked"; } }
sub setExitTAFGracefullyLock     { open Fout, ">$exitTAFGracefullyLock"; print Fout "exitTAFGracefullyString=$exitTAFGracefullyString"; close Fout; }
sub releaseExitTAFGracefullyLock { unlink $exitTAFGracefullyLock; } 
sub exitTAF			 { open Fout, ">$exitTAFGracefullyLock"; print Fout "exitTAFGracefullyString=$exitTAFGracefullyString"; 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 resetTSFile { # fname, fileContent, maxTCExecTime 
	my $fname = "$SvrDrive/$SvrProjName/$resetTSFileName";   $fname = shift if @_; 
	my $content = "";
 	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);
	print " <-> Reset $SvrDrive/$SvrProjName/$resetTSFileName - Done\n"; 
	1;
}

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);
	1;
}

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."_"	;
	if (-e $fname) {;} else { &createFile($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_2  { my $string = shift; $string =~ s/\\/\//g; $string =~ s/\/$tc_pl//; return $string; }	# remove c:\
sub getRoot_4  { my $string = shift; $string =~ s/\w:[\/|\\]//; return $string; }	# remove c:\
sub getRoot_3 { my $string = shift; @_ = split /\\|\//, $string; 			# remove c:\
	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 $_[$#_]; }	# return tc.pl
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]; }	# remove tc.pl

sub prHtml1_strGen() {
	my $localUrl = $url; $localUrl = shift if @_;	
	my $tcPropertyPatternPattern_ = ".*"; ####################### Reset the tcPropertyPatternPattern for index.htm
	my $testsuiteTotalExecTime =  &getTestsuiteTotalExecTime ("$SvrDrive/$SvrProjName/$reportHtml1"); 
	my $tcDescTitle = "<a href=\"${localUrl}/$SvrProjName/_generateExcelReport.html\" title=\"Link to Daily Report. Below link to TC Logs\">"; 
	   $tcDescTitle = sprintf "$tcDescTitle%-${webUI_TCDescWidth}s</a>","   ------------------Testcase Description------------------";
	my $TCCtrToolTip = sprintf "Run Test Suite 24/7 (Avg Time is $testsuiteTotalExecTime)"; 
	my $perl = $^X;  $perl =~ s/\\/\\\\/g;
	my $execTS = sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName SysDrive=$SvrDrive;Execution_24_7=y;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;exec')\" title=\"$TCCtrToolTip\"> Exec</a>");
	my $stopTS = sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName exitTAFGracefullyString=exitTAF;exitTAF')\" title=\"Stop Test Execution gracefully\" >.</a>");
	my $markTS = sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName SysDrive=$SvrDrive;Execution_24_7=n;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;mark')\" title=\"Make the beginning of a execution by \|\"> \|</a>");
	my $listTS = sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName SysDrive=$SvrDrive;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;testcaseNode=testcase;list')\" title=\"Update webUI /o Tags (default)\">S</a>");
	my $listTSAll = sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtml\" onClick=\"RunFile('$perl $scriptName SysDrive=$SvrDrive;$tcPropertyPatternName=$tcPropertyPatternName;tcPropertyPatternPattern=$tcPropertyPatternPattern_;testsuit=$SvrProjName;list')\" title=\"Update webUI /w Tags\">U</a>");
	my $listTAFTestBed      = sprintf("<a href=\"${localUrl}/taf.txt\" title=\"Display TAF Testbed scripts\">E</a>");
	my $indexthProperty = sprintf("<a href=\"${localUrl}/$SvrProjName/tsProperty.txt\" title=\"Display TS property\">L</a>");
	my $tafGlobalVars = sprintf("<a href=\"${localUrl}/_tafGlobalVars.txt\" title=\"Display TAF Global Variables\">T</a>");
	my $indexCmdLog   = sprintf("<a href=\"${localUrl}/_cmdLogs.txt\" title=\"Display TAF Cmd History\">S</a>");
	my $indexFailed = sprintf("<a href=\"${localUrl}/$SvrProjName/index_failed.htm\" title=\"Display *Failed* TCs\">Fail</a>");
	my $indexPassed = sprintf("<a href=\"${localUrl}/$SvrProjName/index_passed.htm\" title=\"Display *Passed* TCs\">Pass</a>");
	my $indexOthers= sprintf("<a href=\"${localUrl}/$SvrProjName/index_others.htm\" title=\"Display *others* TCs\">/</a>");
	my $indexUrlIIS = sprintf("<a href=\"${url}/$SvrProjName/index_http.htm\" title=\"Run TAF-Team Version based on IIS/http\"> <font color=\"white\">TC Manual Command</font></a>");
	my $indexSeconds = "<a title=\"Execution time = $testsuiteTotalExecTime (s) \">(sec)</a>";
	my $indexTitle = sprintf("<a href=\"${localUrl}/index.htm\" title=\"Run TAF-Team Version based on IIS/http\">$web_ui_title</a>");
	my $indexResult = sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtmlSummary\" title=\"Latest TC pass/fail (Gree/Red) Click to Display Test Suite Summary\">".substr ("Result                                                                                                                                               ", 0, $passFailDisplayWidth-7)."</a>");
	my $tmp10 = sprintf("<a href=\"${localUrl}/$SvrProjName/$reportHtmlSummary\" title=\"$reportHtmlSummaryStr\">");
	my $passFailDisplay = &genPassFailDisplay("");
	
my $indexHtml =<<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>${indexTitle}</h2> 
${indexResult}${listTAFTestBed}${listTS}${listTSAll}${indexthProperty}${tafGlobalVars}${indexCmdLog} ${stopTS}${markTS}${execTS} <a title=\"Click Testcase Desc to view TC logs\">$tcDescTitle     ${indexPassed}${indexOthers}${indexFailed}       ${indexSeconds}       ${indexUrlIIS}  </span>
EOF

	return $indexHtml; 
	}
sub prHtml1 {		# print index.htm beginnings
	my $tcPropertyPatternPattern_ = ".*"; ####################### Reset the tcPropertyPatternPattern for 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 $indexHtml = &prHtml1_strGen($url); 
&appendtoFile_ ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml, $indexHtml);

my $indexHtml_http = &prHtml1_strGen($urlHttp); 
&appendtoFile_ ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml_http, $indexHtml_http);
}

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



__END__
		TAF Function Summary  (Sept 27, 2011)
------------------------------------------------------------------------------------------
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;} 
}

#################### Todo list: Functional Requirements ##########################
# * add URL to c:\_TAF\taf.bat (taf.txt)                     		-done 01/29/2013
# * add tsProperty.txt for testsuite1 and testsuite2			-done 01/29/2013
# * bug mapTC shadows the listTC/execTC $rst				-done 01/23/2013 
# * bug when there is no tags (_full_ and _smoketest_), _full_ will break the TAF
# * create testbed regression 
# * modify the ps1_args___powershell_args				-done 01/22/2013
# * add the generateChildTestsuites  					-done 01/16/2013  (need further test)
# * Add thProperty.txt for each TS					-not an issue
# * add the c:\_TAF\_tafGlobalVars.txt &readTAFGlobalVars		-done 01/15/2013
# * c:\_TAF\_cmdLogs.txt can grow very big potentially			-done 01/15/2013
# * Issue: testcaseNode default = testcase000N (comflict between taf/ts and generated/ts) -fixed 01/15/2013
# * But one PS TC failed in the test bed  ps1_arg=powershell_args	-doen 01/15/2013
# * cmdLog.txt TimeSpan    $commandLogLifeSpan		= "- 3 days"; 	-done 01/15/2013
# * add command history to c:\_cmdLogs.txt				-done 01/15/2013
# * remove autoTCDesc related lines (remove tcDesc Serial Number) 	-done 01/15/2013
# * tcDelta needs to be copied from Jan_11B version markdaily 		-done 01/15/2013
# * add _tag_ function (index_faild 	mergethProperty();		-done 01/15/2013
# * add refresh from webUI $listTS,$listTSAll				-done 01/14/2013
# * bug: list should not make the moving bar	$scrollAmount_		-done 01/13/2013
# * testsuite log $externalLogName=... see &getTCLogFname__ 		-done 01/13/2013
# * Format the passFailString	add dumyTC				-done 01/13/2013
# * Pass/Fail link failed  getLastPassFail() and genPassFailOther	-done 01/13/2013 
# * Bug Exec_24_7 will run infinite number for propertyOp		-done 01/13/2013 	(propertyExecCtr)
# * duplicated records in webUI (possible reason/solution) testcaseNode (solution: testcaseNode?)
# * fix todo in the code						-done 01/13/2013	(4 todo left to fix)
# * generateRootIndex copy index.htm_ to index.htm doens't work on some system (need exit IE/index.htm or manual copy)
# * there is recursive call on scanTestsuite (call list)
# * add Regexp::Assemble->new; 		 in the build process		-done 01/04/2013
# * add File::Copy::Recursive dependency in the build process		-done 01/04/2013
# * generate the index_http.htm. 					-In progress (12/26/2012 onhold wait for RubyOnRail)
# * Animate Testsuite bulletin. - generateRootIndex ? 			-in Prog (need testing)
# * Extra searial#. was added in the code. thProperty.txt) - as designed-done 01/01/2012
# * Mark automation every day  by            sub getExecDay 		-done 01/04/2013
# * Full width passFailString (index_Full_Length.htm) 	Add intelegent 	-done 01/02/2012
# * Mark with Automation Note/Mouse Over display 			-done 01/01/2013
# * MouseOver * in the Automation history				-done 12/26/2012 
# * generate taf.pl on e: (other than c:)  taf.pl _TAF=tmp\tmp;genDriver-done 12/26/2012
# * generateExcelReport has $rst = `$cmd`. should &func() 		-done 12/26/2012
# * add Mark by "|" in webUI						-done 12/21/2012
# * add stop TS by "." in webUI						-done 12/21/2012
# * multiple command in squence: list;exec;list;exec			-done 12/18/2012 
# * scan TS under c:\_TAF\ doen't work yet. (errous test bed)		-done 12/20/2012
# * fix bug ps1_arg1= bug	In processTCS				-done 12/20/2012 
# * add function: exitTAFGracefully for any TC  .Execution		-done 12/20/2012
# * multiple commands separated by ;	$isBatchProcessing == 1) { $NofExecutionCtr=0; &tcLoop();} -done 12/18/2012
# * add refresh function to c:\_TAF\index.htm				-done 12/14/2012
# * Stop a specific test execution					-done 12/13/2012 
# * Repeat a specific test case	($markTS)				-done 12/13/2012
# * GeneratePowershellShellTS 						-done 06/06/2012
# * create ps1 testsuite createTS and its test cases			-done 06/01/2012
# * integrate gerneatePShellTestsuite 					-done 06/06/2012
# * remove taf recursive by $makeMark=y (perform improvement)		-done 12/05/201/
# * exitGracefully for each test case					-done 12/12/2012 
# * add generateExcelReport Function					-done 12/06/2012
# * add enterY function							-done 12/10/2012
# * remove _cmd_holder and _desc_holder_				-done 12/11/2012
# * convert listHistory to propertyOP=list_history_tcRunReport  	-done 12/11/2012
# * generate daily Excel report						-done 12/11/2012
# * resetTSFile								-done 12/12/2012
# * make Testcase Description link to Daily Report 			-done 12/12/2012
# * run one TC 24_7							-done 05/01/2012
# * win8 installation							-done 12/05/2012
# * use testsuite for tcFilter, tcDefaultFilter 			-done 12/12/2012
# * generateExcelReport handles performance TC (return NN.NN)  		-done 12/12/2012
* # addURLs will add date-time to the log fname 			-done 12/13/2012
###############################################

############# Low Priority Requirement/Bugs #########
#   Need to setup IIS and _TAF as a virtual directory documentation 
# * multiple tppp filters 	(Very difficult/Low priority)
# * Notif for the expected failure
# * bug: when there is no TC in a TS, the TS * is default to move 
# * generateIndex (including generateRootIndex) based on scanTestsuite - works. but index.htm has a lock on it?  (investigation)
# * multi-TS Execution sequentially or concurrently
# * global $index 
# * handle unexpected reboot scenario

############# todo: MarkTC related Actions #########
# * mark by delta time (every day at 0:00?) 
# * mark with comments (mouse over comments)				-done 12/26/2012
# * 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
# * modify the getProperties to pass regression				-done
# * add removeDuplicated records to handle webUI dup			-done (wrong fix. reversed)
# * scanTestsuite for generated property files _full_, _smoketest_, _regressiontest_ -done (see taf.bat)
# * scanTestsuite for generated property files _full_,  _tcLogAppend.txt was not copied to the _property_ directory - Done
# * c:\_TAF\index.htm concurrency control 				-done
# * Bug fix for generate index_[pass|fail].htm				-done
###################################################################################
############# done : property operations ###############
# * Add 								-done
# * Delete      add=prop:null						-done 
# * Modify	add=prop:newValue					-done 
# * List|get	propertyOp=list_[history_]propName               	-dene 12/11/2012
############ repalced by [set|get]_tcFilter 
# Know Issue:
# When The TS is under c:\_TAF, generateTestsuite will generate c:\_TAF\_TAF.... no index.pl is copied. 
# The original c:\_TAF\... is treated as the test suites
# Q: does the c:\_TAF\_TAF is necessary created? (It won't hurt for now)
#############################################################

##################### Research Topic1: TAF_Team function   ############################
# * Web Service architecture / CGI / RPC / RubyOnRail
# * Browser independency 
# * local run version and /o IIS , support multiple TC Concurrency Control, 
# * Working with new Concurrency Control scheme, TCExecSummary, tcDelay=10
# * Linux porting (convert \\ to / for unix port)

#################### Research Topics2: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					-done
# 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

# thProperty.txt recursive format? update thProperty ? 

__END__
c:\_TAF\taf.pl -processTSs create=c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_pl
c:\_TAF\taf.pl testsuite=c:\_CRB_\AppBuildpath\_automated_testsuites_\_testsuite_pl;tcPropertyName=_full_;generateTestsuiteByDesc

c:\_TAF\taf.pl tcPropertyName=_smoketest_;testsuite=c:\_CRB_\AppBuildpath\_automated_testsuites_\_testsuite_pl;generateTestsuiteByDesc
c:\_TAF\taf.pl tcPropertyName=_regressiontest_;testsuite=c:\_CRB_\AppBuildpath\_automated_testsuites_\_testsuite_pl;generateTestsuiteByDesc
c:\_TAF\taf.pl testsuite=c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_pl/_full_;generateTestsuite
c:\_TAF\taf.pl testsuite=c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_pl/_smoketest_;generateTestsuite
c:\_TAF\taf.pl testsuite=c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_pl/_regressiontest_;generateTestsuite
c:\_TAF\taf.pl testsuite=c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_pl;generateTestsuite
c:\_TAF\taf.pl testsuite=c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_pl;testcaseNode=testcase;generateTestsuite


c:\_TAF\taf.pl taf.pl testsuite=_CRB_\AppBuildpath\_automated_testsuites_\_testsuite_pl;testcaseNode=testcase;list
rem c:\_TAF\taf.pl taf.pl testsuite=_CRB_\AppBuildpath\_automated_testsuites_\_testsuite_pl;list


c:\_TAF\taf.pl -processTSs create=c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_pl
c:\_TAF\taf.pl tcPropertyName=_smoketest_;testsuite=c:\_CRB_\AppBuildpath\_automated_testsuites_\_testsuite_pl;generateTestsuiteByDesc
c:\_TAF\taf.pl testsuite=c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_pl/_smoketest_;generateTestsuite
c:\_TAF\taf.pl testsuite=c:/_CRB_/AppBuildpath/_automated_testsuites_/_testsuite_pl;testcaseNode=testcase;generateTestsuite
c:\_TAF\taf.pl testsuite=_CRB_\AppBuildpath\_automated_testsuites_\_testsuite_pl;testcaseNode=testcase;list



c:\_TAF\taf.pl testsuite=c:\_CRB_\AppBuildpath\_automated_testsuites_\_testsuite_pl;tcPropertyName=_full_;generateTestsuiteByDesc
c:\_TAF\taf.pl testsuite=c:\_CRB_\AppBuildpath\_automated_testsuites_\_testsuite_pl\_full_;generateTestsuite

generateChildTestsuite()   has a recursive call