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 initTAF ); our $VERSION = '0.058.22'; ###################### TAF Global Variables ############################### my %tsProperty;my %tafProperty; my $propertyOp=''; my $regression=0; my $help=0; my $sleep4Display = 1; my $notUsegetTCName= 0; my $tcIdCtr=0; my $ip = 'localhost'; my $tsDriver = "null" ; # cmd-line-overwrite $testDriverName (generated by -e .. index.pl or index.ps1) my $pr2Screen = 1; my $tcIdMin= 0; my $reportHtmlSummaryStr = ''; # String for mouse-over display TC summary my $Execution_24_7 = "n"; my $NofExecution = "1"; my $NofExecutionCtr=0; my $ExecutionLength = "10000 hour"; my $ExecutionType = '>'; my @tcDesc; my $tsFilter=".*"; ###################### TAF Generated Variables ############################### my $scriptName = $0; $scriptName =~ s/\\/\\\\/g; my $workingDir = getcwd(); 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 $c = "c:"; my $taf = "taf.pl"; my $SUTSymbol = "_"; my $tsFilterDefault = "_"; my $tcFilterDefault = ".*"; my $_TAF = "_TAF"; my $SvrDrive = $c.'/'.$_TAF; my $SvrProjName = '_testSuit_'; my $SvrTCName = '_testCase_'; my $SvrTCNamePattern = "*"; my $SvrPropNamePattern = '.*'; my $SvrPropValuePattern = ".*"; my $SvrTCNameExecPattern = ".".$SvrTCNamePattern; my $SvrLogDir = ''.$SvrProjName.''; my $ps1_args = ""; my $exitTAFGracefullyLock = $c.'/'.$_TAF.'/'."_exitTAFGracefully_.txt"; my $performanceMode = "slow4webUI"; # fast4cmd my $generateTestsuiteBAT = $c.'/'.$_TAF."/taf_generateTestsuite.bat"; my $tsFrom =""; my $tsTo =""; ###################### TAF WebUI Default Settings ############################### my $web_ui_title ="Test Automation Framework"; my $webUI_TCDescWidth = 80; my $scrollAmount = 0; my $borderWidth = 0; my $borderStyle = "SOLID"; my $passFailDisplayWidth = 10; my $maxPassFailDisplayWidth = 20; my $reportHtmlSummaryScale = 3600; # in seconds my $reportHtmlSummaryScaleMajor = 12; # in seconds my $tsProperty = 'tsProperty.txt'; my $testcaseNode = ""; # enforce no mix-level scan happens my $reportHtml = 'index.htm'; my $reportHtml1 = '_tcReport_.html'; my $reportHtmlHistory = '_tcReportHistory_.html'; my $reportHtmlSummary = '_tcReportSummary_.html'; my $tc_pl = "tc.pl"; my $reportHtml_http = 'index_http.htm'; # $reportHtml."_http"; my $reportHtml1_http = '_tcReport_.html'."_http"; my $reportHtmlHistory_http = '_tcReportHistory_.html'."_http"; my $url = 'file:///'.$SvrDrive; my $urlHttp = 'http://'.$ip.'/'.$_TAF; sub new { my $package = shift; return bless({}, $package); } sub tcLoop { my $returnValue; &releaseExitTAFGracefullyLock(); while (($Execution_24_7 eq 'y') || ($NofExecution > $NofExecutionCtr)) { $NofExecutionCtr++; if ($pr2Screen == 1) { if (($NofExecution == 1) && ($Execution_24_7 ne 'y')){ print "Processing ......\n" ; } else {print "Processing ($NofExecutionCtr\/$NofExecution) ......\n" ; } } else { print "";} if (($propertyOp =~ /^\s*$/) || ($propertyOp =~ /tcDescAuto/i)) {&tcPre(); &tcMain_(); &tcPost(); } else { &tcMain_(); } # TC Property Process if ($pr2Screen==1) {print " - Completed -\n"; } else { print "";} } return $returnValue; } sub tcPre { if (-e $SvrDrive.'\\'.$SvrProjName) {;} else { print "$SvrDrive/$SvrProjName doesn't exist.\n"; exit; } ##################### PrePRocessor ##################### &createFile_($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1,""); &createFile_($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtmlHistory,""); &appendtoFile_($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtmlHistory,"
\n");
 	&createFile_($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1_http,"");
	########################################################
}

sub tcMain_ { $notUsegetTCName= 1; find(\&recursiveSearchtcMain, $SvrDrive); }
sub recursiveSearchtcMain() { 
	my $returnValue ='';
	if ($SvrTCNamePattern eq '*') { $SvrTCNamePattern = '.*';} 

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

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

		my $tmp = $tcOp;

		if (    ($tcOp !~ /^\s*$/)&&($SvrTCName =~/$SvrTCNameExecPattern/)&&($tcIdCtr >= $tcIdMin) 
			&& 
			(&getProperties(&getTCName($SvrTCName) , $tcPropertyPatternName, "value") =~ /$tcPropertyPatternPattern/i)
			&&
			(&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 generatTestsuite
				my $tcDescAuto="";
				if ($#tcDesc eq 0 ) {;} else { $tcDescAuto = "add=tcDesc:".shift @tcDesc; }
				my $tcDescAuto_ = $tcDescAuto; $tcDescAuto =~ s/_space_/ /g; $tcDescAuto =~ s/_column_/:/g; $tcDescAuto =~ s/_eq_/=/g; 
				printf "%-20s %s %s\n", "processProperty:", &getTCName($File::Find::name),$tcDescAuto;
				&processProperty("",&getTCName($File::Find::name), $tcDescAuto_);
			} elsif (($propertyOp =~ /_doit_/i) || ($propertyOp =~ /^\s*_?get_/i)) {   					# property Operation (_doit_)
				my $propertyOp_  = $propertyOp; 
				$propertyOp_  =~ s/_doit_//g;
				my $rst = &processProperty("",&getTCName($File::Find::name), $propertyOp_);
				print "$File::Find::name:    $propertyOp = $rst\n";
			} else {
				print "[TS/TC=$File::Find::name]  propertyOp=$propertyOp    _doit_\n"; # property Operation (print it)
			}
		        ##################### Property OPeration End   ####################
		   } # else 
		   if (($propertyOp =~ /tcDescAuto/i) || ($propertyOp =~ /^\s*$/)) {		# TC Exec Processor
			##################### TC Operation Start ######################
			if ($scrollAmount ==0 and $borderWidth ==0) { 					  # TC Execution
				&updateWeb_(&getDir($File::Find::name),1, $borderWidth, "SOLID", $ExecutionType);
				if ($performanceMode =~ /slow4webUI/i) { &updateTestsuitePassFail ()	;}
				$returnValue = $returnValue. &processTC("","$tcOp=$eachTC",$pr2Screen)."\n"; 
				if ($performanceMode =~ /slow4WebUI/i) {
				&logTC($eachTC);						# TC Logging	  -> tesesuite\testcase\_tcLog.html
				&reportTCHistory($eachTC);					# TC ReporHistory -> testsuite\_tcReportHistory_.html
				&reportTCSummary ();
				&updateTestsuitePassFail ()	;
				}
				&updateWeb_(&getDir($File::Find::name),0, $borderWidth, "SOLID");
				if ( &getDir($File::Find::name) =~ /_LBP/i) { $sleep4Display = 10; }
				if (($tcOp !~ /list/) && ($tcOp !~ /mark/)) { sleep $sleep4Display;}
			} elsif ( $scrollAmount != 0 ) {								# Handle different TC exec state
				if       (($scrollAmount != 0 and $borderWidth== 0 )) { $borderWidth = 1; $borderStyle = "DOTTED"; }
				elsif    (($scrollAmount != 0 and $borderStyle =~ /DOTTED/i)) {$borderWidth =1; $borderStyle = "SOLID"; }
				elsif    (($scrollAmount != 0 and $borderStyle =~ /SOLID/i)) {$scrollAmount=0; $borderWidth =0; $borderStyle = "SOLID"; }
				if ($performanceMode =~ /slow4WebUI/i) {
				&logTC($eachTC);						# TC Logging	  -> tesesuite\testcase\_tcLog.html
				&reportTCHistory($eachTC);					# TC ReporHistory -> testsuite\_tcReportHistory_.html
				&reportTCSummary ();
				&updateWeb_(&getDir($File::Find::name),$scrollAmount, $borderWidth, $borderStyle);
				}
			} ##################### TC Operation End ######################
		   } 

		}

		$scrollAmount = 0; $borderWidth = 0; $borderStyle = "SOLID";
		#}	# Property Filter 							# Passing $scrollAmount, $borderWidth, $borderStyle, 
	} # TC Filter
}
sub tcPost {
	##################### Post PRocessor ###################
 	&appendtoFile_		($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtmlHistory,"
\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() ; # &removeDuplicate ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml) ; # have bug. will create empty index.htm # &removeDuplicate ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml_http); &generateRootIndex () ; &updateTestsuiteHTA () ; &updateTestsuitePassFail () ; ######################################################## } ####################### 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 ($_ = ) { 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 $!;} sub copyTS { shift; print "copy $tsFrom -> $tsTo\n"; rcopy ($tsFrom, $tsTo) or die $!;} #######################generate Property TCs from desc sub generateTestsuiteByDesc { $tsFilterDefault =~ s/\\/\//g; &tcMain_1(); 1; } sub tcMain_1 { print " Scanning for testsuites at $tsFilterDefault ......\n"; find(\&recursiveSearchtcMain_1, $tsFilterDefault); 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 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 "; } my $perlCode=< 1) { if (-e $tsDirChild) {;} else { mkpath $tsDirChild;} 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"; } 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;} if ($tsFilterDefault =~/_doit_/i) { $doit='y'; $tsFilterDefault =~ s/_doit_//i;} if ($tsFilterDefault =~ /^$c/) { @dir = glob "${tsFilterDefault}*"; } else { @dir = glob "${c}\\${tsFilterDefault}*"; } foreach my $each (@dir) { $each =~ s/\\/\//g; find(sub { if (($File::Find::name =~ /index\.\w+$/i) && ($File::Find::name !~ /${c}\/${_TAF}/i)&&($File::Find::name !~ /${c}\\${_TAF}/i)) { my $dirName = $File::Find::name; $dirName =~ s/[\\|\/]index..+$//g; $tsFilterDefault =~ s/\\/\//g; # if ($dirName =~ /$tsFilter/i) { if ($dirName =~ /$tsFilterDefault/i) { $ps1_args =~ s/ /___/g; my $cmd = sprintf "$SvrDrive/$taf workingDir=$dirName;web_ui_title=$dirName;ps1_args=$ps1_args;generateTestsuite" ; print "$cmd\n"; if ($doit =~ /\by\b/) { print "Running ...\n"; $cmd =~ s/\//\\/g; my $rst = `$cmd`; print $rst."\n";} } } }, $each); } 1; } #######################generateRootIndex { sub generateRootIndex { ######### generate index.htm my %tafUI; &readTAFProperty(); # read %tafProperty; #### part 1 #### open INDEX, ">$SvrDrive/index.htm_"; print INDEX<

Automated Test Suites on $ip

    EOF find(sub { if ($File::Find::name =~ /index\.htm$/i) { my $tmp= $File::Find::name; my $tmp2 = $File::Find::name; $tmp=~ s/$SvrDrive//; $tmp2 =~ s/\/index.htm//g; if ($tafProperty{$tmp2} ) { $tmp2 = sprintf("%-120s", $tafProperty{$tmp2}); } # todo hardcoded 120 else { $tmp2 = sprintf("%-120s", $tmp2); } $tafUI{$tmp2}="
  • $tmp2$SvrDrive$tmp\n" if ($tmp ne "/index.htm"); # print INDEX "
  • $tmp2$SvrDrive$tmp\n" if ($tmp ne "/index.htm"); } }, $SvrDrive); foreach my $each1 (sort keys %tafUI) { print INDEX $tafUI{$each1}; } print INDEX <
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<

Automated Test Suites on 10.24.2.66

    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 "
  • $tmp2\n" if ($tmp ne "/index_http.htm"); } }, $SvrDrive); print INDEX <
EOF ; close INDEX; move ($SvrDrive.'/index_http.htm_', $SvrDrive.'/'."index_http.htm"); #### part 2 #### } ####################### read Testsuite web_ui_title sub readWebTitle{ my $dir = shift; my %prop; my $webTitle = "Test Automation Framework"; if (-e "$dir/tsProperty.txt") { open Fin, "$dir/tsProperty.txt"; while ($_ =) { 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 ($_ = ) { if ($_ =~ /^\s*$index_"; while ($_ = ) { if ($_ =~ /tcPropertyPatternPattern/) { $_ =~ s/tcPropertyPatternPattern=\.\*/tcPropertyPatternPattern=fail/g; } if ($_ =~ /RunFile/) { $_ =~ s/index\.htm/index_failed\.htm/g; } if (&getLatestPassFail($_) =~ /color:gray;/i) { ; } elsif (&getLatestPassFail($_) =~ /color:green;/i) { ; } else { print Fout $_; } } close Fout; close Fin; } } elsif ($index=~ /index_http\.htm\s*$/ ) { $index_ = $index; $index_ =~ s/\.htm/_failed\.htm/; if (-e $index) { open Fin, $index; open Fout, ">$index_"; while ($_ = ) { if (&getLatestPassFail($_) =~ /color:gray;/i) { ; } elsif (&getLatestPassFail($_) =~ /color:green;/i) { ; } else { print Fout $_; } } close Fout; close Fin; } } ####################### failed.htm ##################### ####################### pass.htm ##################### if ($index=~ /index\.htm\s*$/ ) { $index_ = $index; $index_ =~ s/\.htm/_passed\.htm/; if (-e $index) { open Fin, $index; open Fout, ">$index_"; while ($_ = ) { if ($_ =~ /tcPropertyPatternPattern/) { $_ =~ s/tcPropertyPatternPattern=\.\*/tcPropertyPatternPattern=pass/g; } if ($_ =~ /RunFile/) { $_ =~ s/index\.htm/index_passed\.htm/g; } if (&getLatestPassFail($_) =~ /color:gray;/i) { ; } elsif (&getLatestPassFail($_) =~ /color:red;/i) { ; } else { print Fout $_; } } close Fout; close Fin; } } elsif ($index=~ /index_http\.htm\s*$/ ) { $index_ = $index; $index_ =~ s/\.htm/_passed\.htm/; if (-e $index) { open Fin, $index; open Fout, ">$index_"; while ($_ = ) { if (&getLatestPassFail($_) =~ /color:gray;/i) { ; } elsif (&getLatestPassFail($_) =~ /color:red;/i) { ; } else { print Fout $_; } } close Fout; close Fin; } } ####################### pass.htm ##################### ####################### other.htm ##################### if ($index=~ /index\.htm\s*$/ ) { $index_ = $index; $index_ =~ s/\.htm/_others\.htm/; if (-e $index) { open Fin, $index; open Fout, ">$index_"; while ($_ = ) { 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 ($_ = ) { if (&getLatestPassFail($_) =~ /color:green;/i) { } elsif (&getLatestPassFail($_) =~ /color:red;/i) { ; } else { print Fout $_; } } close Fout; close Fin; } } ####################### other.htm ##################### } #######################generateFailedTCHtml sub getLatestPassFail { $_ = shift; my $color; if ($_ =~ /^\s*/) { if ($_ =~ /^\s*\s*\*/) {$color = $1;} else {$color = "gray";} } if ($color) { return "color:$color;";} else {return "_";} } sub updateWeb { my %tsProperty; my $tcname = 'TC_tc1'; $tcname = shift if @_ ; my $scrollamount = 0 ; $scrollamount = shift if @_ ; $tcname = &getTCName($tcname); $tcname =~ s/\\/\//g ; if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml) { open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml ; open Fout, ">".$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_" ; while ($_ = ) { 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 ($_ = ) { chop; if ( &hungryMatch($_,"\/\/\/","index.htm") ) { my $ts= &hungryMatch($_,"\/\/\/","index.htm") ; &createTestsuiteHTA ($ts); } } } sub tsPostProcessPlugin { open Fin, $SvrDrive."/index.htm" || die "Can't open index.htm"; while ($_ = ) { chop; if ( &hungryMatch($_,"/\/\/\/","index.htm")) { my $ts= &hungryMatch($_,"\/\/\/","index.htm"); print "postProcessPlugin: $ts\n";} } } sub updateTestsuitePassFail { if (-e $SvrDrive."/index.htm" ) { open FinIndex, $SvrDrive."/index.htm" || die "Can't open index.htm"; while ($_ = ) { 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', " Run $testsuite\/ts.hta

") ; } ################################################################################ # ################################################################################ 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 ($_ = ) { chop; # if ($web_ui_title =~ /Test Automation Framework/i) { # if ($_ =~ /web_ui_title\s*:\s*(.+):\s*web_ui_title/) { if ($_ =~ /web_ui_title\s*:\s*(.+)\s*:\s*web_ui_title/) { $web_ui_title = $1; } # } my $tcname, my $tcdesc; ($tcname, $tcdesc) = split /[\|]/, $_; if ($tcdesc) { $tcname =~ s/^\s*//; $tcname =~ s/\s*$//; # $tcdesc =~ s/^\s*//; $tsProperty{$tcname}= $tcdesc; } } close Fin; } } ################################################################################ # ################################################################################ sub readTAFProperty { if ( -e $SvrDrive.'/'."tsProperty.txt") { open Fin, $SvrDrive.'/'."tsProperty.txt"; while ($_ = ) { chop; if ($web_ui_title =~ /Test Automation Framework/i) { if ($_ =~ /web_ui_title\s*:(.+):\s*web_ui_title/) { $web_ui_title = $1; } } my $tcname, my $tcdesc; ($tcname, $tcdesc) = split /[\|]/, $_; if ($tcdesc) { $tcname =~ s/^\s*//; $tcname =~ s/\s*$//; # $tcdesc =~ s/^\s*//; $tafProperty{$tcname}= $tcdesc; } } close Fin; } } ################################################################################ # Subroutine Name : logTC # Function: create TC _tcLog.html for each TC # Input Parameters: Test Case name # Output/Returns : c:\inetpub\wwwroot\*.html ################################################################################ sub logTC { # Update TC Log on webUI (TH:WebUI) my $currentTime = &UnixDate( "now", "%m/%d/%Y %H:%M:%S %Z" ); my $tcname = shift; $tcname = &getTCName ($tcname); if (&getTCLogFname($tcname) =~ /_tcLog\.txt\s*$/ ) { my $webLogText = &readFile("$tcname\\_tcLog.html"); $webLogText =~ s/\s*\s*

\s*//;
	       	$webLogText =~ s/<\/pre>\s*<\/body>\s*<\/html>\s*//;
	       	$webLogText =~ s/\n/_nl_/g;
	       	$webLogText =~ s/\s*_nl_\s*/\n/g;
    		my $fileText = &readFile(&getTCLogFname($tcname)); # todo Histery
    		my $fileText_= &readFile(&getTCLogFname_($tcname)); # for _tcLogAppendix_.txt (pyAnvil logs)
    		if (-e $tcname) {;} else {mkpath $tcname;}
	 	open Fout, "> $tcname\\_tcLog.html" || die "Warning: $tcname\\_tcLog.html doesn't exist\n";
		print Fout "
\n";
         	print Fout "==================== Update on $currentTime Start ===================== $tcname\n";
    		print Fout  $fileText_ if ($fileText_);
    		print Fout  $fileText;
		print Fout "==================== Update on $currentTime End   ===================== $tcname\n\n"; 
         	print Fout "
\n"; close Fout; } elsif (&getTCLogFname ($tcname) =~ /_tcLogAppend\.txt\s*$/) { my $webLogText = &readFile("$tcname\\_tcLog.html"); $webLogText =~ s/\s*\s*
\s*//;
	        $webLogText =~ s/<\/pre>\s*<\/body>\s*<\/html>\s*//;
	        $webLogText =~ s/\n/_nl_/g;
       		$webLogText =~ s/\s*_nl_\s*/\n/g;

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

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

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

    		if (-e $tcname) {;} else {mkpath $tcname;}
		open Fout, "> $tcname\\_tcLog.html" || die "Warning: $tcname\\_tcLog.html doesn't exist\n";
		print Fout "
\n";
         	print Fout "==================== Update on $currentTime Start ===================== $tcname\n";
    		print Fout  $fileText_ if ($fileText_);
    		print Fout  $fileText;
		print Fout "==================== Update on $currentTime End   ===================== $tcname\n\n"; 
		print Fout $webLogText;
         	print Fout "
\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 "
\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 "
\n"; close Fout; } } rmtree &getTCLogFname ($tcname) ; return " tcLog[Append].[txt|html] are refreshed"; } sub addURLs { my $return=""; foreach my $each (split "\n", shift ) { $_ = $each; s/_/_underscore_/g; s/\s/_ws_/g; s/\./_dot_/g; s/\\/_backslash_/g; s/\//_slash_/g; s/:/_col_/g; s/-/_dash_/g; s/\(/_leftPara/g; s/\)/_rightPara/g; s/\W//g; s/\_ws_/ /g; s/_dot_/\./g; s/_backslash_/\\/g; s/_slash_/\//g; s/_col_/:/g; s/_dash_/-/g; s/_underscore_/_/g; s/_leftPara/\(/g; s/_rightPara/\)/g; if (($_ !~ /href=\"/) && (/(.+)($c\S+)\s(.?)/i)) { $return = $return.$1."$_$3\n"; } else { $return = $return.$_."\n"; } } $return ; } sub ps12txt { my $return=""; foreach my $each (split "\n", shift ) { $_ = $each; s/_/_underscore_/g; s/\s/_ws_/g; s/\./_dot_/g; s/\\/_backslash_/g; s/\//_slash_/g; s/:/_col_/g; s/-/_dash_/g; s/\W//g; s/\_ws_/ /g; s/_dot_/\./g; s/_backslash_/\\/g; s/_slash_/\//g; s/_col_/:/g; s/_dash_/-/g; s/_underscore_/_/g; s/^\s*//g; $return = $return."\n".$_; } $return ; } sub addUrl { my $return; my $str = shift; foreach my $each (split /\n/, $str) { if ($each =~ /^\s*(.+\.html)/) { my $line = $1; $line =~ s/^\s*//g; $line =~ s/\s*$//g; $line =~ s/\\/\//g; $line =~ s/HTML:\s*/file:\/\/\//i; $line =~ s//file:\/\/\//; $return = $return. "$each\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. "$each\n"; } else { $return = $return.$each."\n"; } } return $return; } ################################################################################ # Subroutine Name : getTCLogFname # Function: get valid Log (new log) fname # Input Parameters: c:\TC*\_thLog.txt # Output/Returns : noLog or hasWWWLog ################################################################################ sub getTCLogFname { # Determine if a log exists (TH:TC Report) my $tcName = shift; my ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks ); my $mtimeLogWeb; if (-e $tcName.'/thProperty.txt' ) { ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks ) = stat($tcName.'\\'.'thProperty.txt'); } my $tcNameLog = $tcName."/_tcLogAppend.txt"; if (-e $tcNameLog) { my ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtimeLog, $ctime, $blksize, $blocks ) = stat($tcNameLog); if ($mtimePropertyFile - $mtimeLog>= 0 ) { return $tcNameLog; } } $tcNameLog = "$tcName/_tcLog.txt"; if (-e $tcNameLog) { my ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtimeLog, $ctime, $blksize, $blocks ) = stat($tcNameLog); if ( $mtimePropertyFile - $mtimeLog>= 2 ) { return $tcNameLog; } } return "noLog"; } sub getTCLogFname_ { # Determine if a log exists (TH:TC Report) my $tcName = shift; my ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks ); my $mtimeLogWeb; if (-e $tcName.'\\thProperty.txt' ) { ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtimePropertyFile, $ctime, $blksize, $blocks ) = stat($tcName.'\\'.'thProperty.txt'); } my $tcNameLog = $tcName."\\_tcLogAppend_.txt"; if (-e $tcNameLog) { my ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtimeLog, $ctime, $blksize, $blocks ) = stat($tcNameLog); if ($mtimePropertyFile - $mtimeLog>= 0 ) { return $tcNameLog; } } $tcNameLog = "$tcName\\_tcLog_.txt"; if (-e $tcNameLog) { my ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtimeLog, $ctime, $blksize, $blocks ) = stat($tcNameLog); if ( $mtimePropertyFile - $mtimeLog>= 2 ) { return $tcNameLog; } } return "noLog"; } sub reportTCSummary { $reportHtmlSummaryStr = ''; my $MaxTCExecTime = 10; # todo Hard coded veriable open Fin, "$SvrDrive/$SvrProjName/$reportHtmlHistory" || die "Can't open _tcReportHistory.html"; my $fname_ = $SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlSummary."_"; while (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlSummary."_") { my $mtime = ( stat $fname_)[9]; my $current_time = time; my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; } open Fout, "> $SvrDrive/$SvrProjName/$reportHtmlSummary"."_" || die "Can't open _tcReportSummary_.html"; $reportHtmlSummaryStr = "
\n"; $reportHtmlSummaryStr = $reportHtmlSummaryStr . " ";
	$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 ($_ =) { 
	chop;
	if (($_ =~ /(testcase\d+)/) &&( $passCtr ==0 )) {
		$tcName = $1;	
		$reportHtmlSummaryStr = $reportHtmlSummaryStr . "\n$tcName: ";
		$_ = ;
		if ($_ =~ /^\s+(\w+)\s+\w+\s+(\d+\-\d+\-\d+\s+\d+:\d+:\d+)\s+/) {
		$_ =~ /^\s+(\w+)\s+\w+\s+(\d+\-\d+\-\d+\s+\d+:\d+:\d+)\s+/;
		$passFail = $1; $dateTime= $2; $date1=&ParseDate($dateTime); 
		if (&Date_Cmp( &ParseDate($initStartTime), &ParseDate($dateTime) ) >=0 ) { $initStartTime = $dateTime; }
		if (&Date_Cmp( &ParseDate($endStartTime),  &ParseDate($dateTime) ) <=0 ) { $endStartTime  = $dateTime; }
		if ($passFail =~ /pass/i) { $passFail = '*';	} elsif ($passFail =~ /fail/i) { $passFail = '*';} elsif ($passFail =~ /mark/i)  {$passFail ="|";}
		$reportHtmlSummaryStr = $reportHtmlSummaryStr . $passFail;
		}
	} elsif (/^\s+(\w+)\s+\w+\s+(\d+\-\d+\-\d+\s+\d+:\d+:\d+\s+)/) {
		$_ =~ /^\s+(\w+)\s+\w+\s+(\d+\-\d+\-\d+\s+\d+:\d+:\d+\s+)/;
		$passFail = $1; $dateTime= $2;
		if ($passFail =~ /pass/i) { $passFail = '*';	} elsif ($passFail =~ /fail/i)  { $passFail = '*';} elsif ($passFail =~ /mark/i) {$passFail ="|";} elsif ($passFail =~ /null/i) { $passFail = "_";}
		$date2=&ParseDate($dateTime); 
		if (&Date_Cmp( &ParseDate($initStartTime), &ParseDate($dateTime) ) >=0 ) { $initStartTime = $dateTime; }
		if (&Date_Cmp( &ParseDate($endStartTime),  &ParseDate($dateTime) ) <=0 ) { $endStartTime  = $dateTime; }

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


		$reportHtmlSummaryStr = $reportHtmlSummaryStr . $passFail;
	}
}

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

	$reportHtmlSummaryStr = $reportHtmlSummaryStr. "\n_replace_here_\n";
	$reportHtmlSummaryStr = $reportHtmlSummaryStr .  "
\n"; my $tmp = "---------- |<-- ".&UnixDate($endStartTime, "%m/%d/%Y %H:%M:%S %Z")." ---------- $SvrDrive/$SvrProjName Test Summary -----...... <--|". &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: ".&getTCName($tcname)." -----------------------\n"); &appendtoFile_ ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtmlHistory, $fileText); } sub reportTCHistory { my $tcIdCtr_ = $tcIdCtr; my $tcname = shift; $tcIdCtr=1; &createFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,""); &appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"
\n");
find(sub { if ($File::Find::name =~ /tc\.pl$/i) {
			$SvrTCName = $File::Find::name; 
			$SvrTCName =~ s/\/tc.pl//g;
	my $fileText = sprintf "%10s %s", "", &reportTC($tcname,"","History");
	&appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory, " ---------------------- TestCase:  ".&getTCName($tcname)." -----------------------\n");
	&appendtoFile_ ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory, $fileText);
	$tcIdCtr++;
		}
	 }, "$SvrDrive/$SvrProjName");
 	&appendtoFile_($SvrDrive.'/'.$SvrProjName.'/'.$reportHtmlHistory,"
\n") ; $tcIdCtr = $tcIdCtr_; } ################################################################################ # Subroutine Name : reportTC # Function: report TC results on STDOUT and Update TCProj HTML # Input Parameters: TC Name # TC PropertyName = tcRunResult # TC Report Type: 0 = latest 1 = historyical # Output/Returns : TC Reports displayed on webUI ################################################################################ sub reportTC() { # TC Report Function (TH:TC Report) my $tcPropertyPatternPattern_ = ".*"; ####################### Reset the tcPropertyPatternPattern for index.htm my $cmd=''; $cmd = shift; if ($cmd !~ /^\s*cmd\s*=/i) { unshift @_, $cmd; } ; my $timeSpan = "2000!now"; my $tcname = $_[0]; my $propertyPattern = $_[1]; my $reportType = $_[2]; $tcname = &getTCName($tcname); my ($timeSpanStart, $timeSpanEnd, $isInSpan, $beautifiedStr, $beautifiedStr4Web); my $returnValue=""; my ($propertyName, $startTime, $endTime, $comment1, $comment2) ; my $passCtr =0; my $failCtr = 0; my $totalTime=0; my $avgResponseTime; my $propertyValue =''; my $totalTimeDummy; my $passFailDisplay=""; &readTestSuitProperty(); if( $propertyPattern =~ /^\s*$/) { $propertyPattern = 'tcRunResult';} if( $reportType =~ /^\s*$/) { $reportType = 'lastValue';} if ($timeSpan) { $_ = $timeSpan; ($timeSpanStart, $timeSpanEnd ) = split( /!|\|/, $timeSpan ); $timeSpanStart = &ParseDate($timeSpanStart); $timeSpanEnd = &ParseDate($timeSpanEnd); } my $tcPassFailDisplayWidth = 0; # ############ get maxPassFailDisplayWidth ################# open Fin, "$tcname/thProperty.txt" || die "Can't open file:$!"; ################## Read Property File # ############################## Read Property File to update reportHtmlHistory ########################### while ( $_ = ) { chop; if ( $_ =~ /$propertyPattern/i ) { ( $propertyName, $propertyValue, $startTime, $endTime, $totalTimeDummy, $comment1, $comment2) = split( '\|', $_); my $flag1 = &Date_Cmp( &ParseDate($startTime), &ParseDate($timeSpanStart) ); my $flag2 = &Date_Cmp( &ParseDate($timeSpanEnd), &ParseDate($endTime) ); if ( ( $flag1 >= 0 ) && ( $flag2 >= 0 ) ) { $isInSpan = 1; } else { $isInSpan = -1; } my $date1=&ParseDate($startTime); my $date2=&ParseDate($endTime); my $delta=&DateCalc($date1,$date2); $delta =~ s/\+//g; my ($Y,$M,$W,$D,$H,$MIN,$S) = split /:/, $delta; my $totalSec = $D * 24 * 3600 + $H * 3600 + $MIN * 60 + $S; if ($propertyValue =~ /^\s*[\d|.]+\s*$/) { $totalSec = $propertyValue; $propertyValue = "Perf";} if ( $isInSpan == 1 ) {; if ( $propertyPattern =~ /tcRunResult/i ) { $tcPassFailDisplayWidth= $tcPassFailDisplayWidth + 1 ; } } # endif for InSpan } # endif for /propertyPattern/ } close Fin; # todo no-intellegence now if (($passFailDisplayWidth < $tcPassFailDisplayWidth) and ($tcPassFailDisplayWidth < $maxPassFailDisplayWidth)) { $passFailDisplayWidth = $tcPassFailDisplayWidth; } # todo else { $passFailDisplayWidth = $maxPassFailDisplayWidth;} ############ get maxPassFailDisplayWidth ################# open Fin, "$tcname/thProperty.txt" || die "Can't open file:$!"; ################## Read Property File ############################## Read Property File to update reportHtmlHistory ########################### while ( $_ = ) { chop; if ( $_ =~ /$propertyPattern/i ) { ( $propertyName, $propertyValue, $startTime, $endTime, $totalTimeDummy, $comment1, $comment2) = split( '\|', $_); my $flag1 = &Date_Cmp( &ParseDate($startTime), &ParseDate($timeSpanStart) ); my $flag2 = &Date_Cmp( &ParseDate($timeSpanEnd), &ParseDate($endTime) ); if ( ( $flag1 >= 0 ) && ( $flag2 >= 0 ) ) { $isInSpan = 1; } else { $isInSpan = -1; } my $date1=&ParseDate($startTime); my $date2=&ParseDate($endTime); my $delta=&DateCalc($date1,$date2); $delta =~ s/\+//g; my ($Y,$M,$W,$D,$H,$MIN,$S) = split /:/, $delta; my $totalSec = $D * 24 * 3600 + $H * 3600 + $MIN * 60 + $S; if ($propertyValue =~ /^\s*[\d|.]+\s*$/) { $totalSec = $propertyValue; $propertyValue = "Perf";} if ( $isInSpan == 1 ) { if ( $propertyPattern =~ /tcRunResult/i ) { $beautifiedStr = sprintf "%15s %-15s %-25s%-s", $propertyValue, $totalSec.'s', $startTime, $comment1; if ($propertyValue =~ /pass/i) {$passCtr++; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."p";} if ($propertyValue =~ /fail/i) {$failCtr++; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."f";} if ($propertyValue =~ /mark/i) { ; $totalTime =$totalTime + $totalSec; $passFailDisplay = $passFailDisplay."m";} } else { $beautifiedStr = $_; } # endif for /tcRunResult/ if ( $reportType =~ /history/i ) { # return property history # $returnValue .= "$beautifiedStr\n"; $returnValue = "$beautifiedStr\n$returnValue"; } elsif ( $reportType =~ /lastValue/i ) { # returen last property $returnValue = $beautifiedStr; } elsif ( $reportType =~ /forWeb/i ) { # for the web $returnValue .= $beautifiedStr4Web; } } # endif for InSpan } # endif for /propertyPattern/ } ##################### ############################## Read Property File to update reportHtmlHistory ########################### if ($passCtr + $failCtr == 0) { ########## Generate TC webUI string $avgResponseTime = 0; } else { $avgResponseTime = $totalTime / ($passCtr + $failCtr); } my $qtpHost; my $ATResultFname; my %color; my $color = 'gray'; my @color; my $colorIndex = 0; my $QASvrName; my $expFailure=""; if ($propertyValue =~ /pass/i) { $color = "Green"; } elsif ($propertyValue =~ /fail/i) { $color = 'Red'; } elsif ($propertyValue =~ /expected\s*fail/i) { $expFailure = "_Expected_Failure_ "; } $color[0]=1; ##### testcase Desc #### my $TCDesc_displayTip = "Click to view TC logs"; my $TCDesc_display ; my $TCDesc_display_ ; if ($tsProperty{$tcname}) { #$TCDesc_display = sprintf "%-80s", $tsProperty{$tcname}; ###### Handle expected failure if (($tsProperty{$tcname} =~ /_expected_fail_/i) && ($propertyValue =~ /fail/i)){ $color = "Green"; } if (($tsProperty{$tcname} =~ /_expected_fail_/i) && ($propertyValue =~ /pass/i)){ $color = "Red"; } ###### Handle expected failure $TCDesc_display_ = $expFailure.$tsProperty{$tcname}; if (length($TCDesc_display_) <= $webUI_TCDescWidth ) { # todo hardcoded $TCDesc_display = sprintf "%-80s", $TCDesc_display_; } else { $TCDesc_display = sprintf "%-80s", substr $TCDesc_display_, 0, $webUI_TCDescWidth; $TCDesc_displayTip = $tsProperty{$tcname}; } } else { $TCDesc_display = sprintf "%-80s", $tcname; } # prHtml3 mark for search my $tcSerialN = $TCDesc_display; if ($tcSerialN =~ /^\s*\d+\s+/) {$tcSerialN =~ /^\s*(\d+)\s+/; $tcSerialN = "$1"; if ($tcSerialN) {;} else {$tcSerialN = "";}} my $dirRoot = &getRoot($tcname); my $TCCtrToolTip = sprintf "Run Test (Testcase Number == $tcSerialN [%s])", &timeConvert($avgResponseTime); my $TCCtrToolTipMin = sprintf "Run Tests (Testcase Number >= $tcSerialN)" ; my $TCScrollAmount = 0; my $CtrSeparator = "|"; my $perl = $^X; $perl =~ s/\\/\\\\/g; my $tmp11= sprintf(""); $passFailDisplay = &genPassFailDisplay($passFailDisplay); my $tmp = sprintf( "$passFailDisplay${tmp11}. %s %s%-${webUI_TCDescWidth}s %5d/%-5d %6d(s) %s \n", '>', '>|', $TCDesc_display, $passCtr, $failCtr, $avgResponseTime, $tcname.'/tc.pl', ); # http # todo: http miss the runPropertyPattern and tcIdMin function, ExecutionType my $tmp_http = sprintf( "
  • %-80s Pass/Fail: %5d$CtrSeparator%-5d %6d(s) %s
  • \n", $TCDesc_display, $passCtr, $failCtr, $avgResponseTime, $tcname.'/tc.pl', ); if ($cmd =~ /noprint/i) {;} else { &appendtoFileUniq_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1, $tmp ); &updateWeb1_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml, $tmp ); &appendtoFileUniq_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml1_http, $tmp_http ); &updateWeb1Http_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml_http, $tmp_http ); } close Fin; if ($returnValue) {$returnValue =~ s/^\s*//g;} else {$returnValue = "";} return $returnValue; } sub genPassFailDisplay { my $str = shift; $str = reverse $str; $str = $str. " "; $str = substr ($str, 0, $passFailDisplayWidth); $str =~ s/p/*<\/a>/g; $str =~ s/f/*<\/a>/g; $str =~ s/m/|/g; if ($str =~ /^\s*$/) { $str = &genStr($passFailDisplayWidth);} return $str; } sub genStr { my $strLen = shift; my $return=""; for (my $i = 0; $i < $strLen; $i++) { $return .= " "; } $return; } sub processTSs{ shift; my $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); } else { print "Unrecognized Testsuite Command: $varName\n"; } } } } sub processTCs{ shift; my $isBatchProcessing = 1; my $tmp = shift; @_ = split /;/, $tmp; &genDriver_taf_pl (); foreach my $each (@_) { if ($each !~ /=/) { $isBatchProcessing = 0; if (($each =~ /\blistVars\b/i) || ($each =~ /\bgetVars\b/i)) { return &getGlobalVars() ; } elsif ($each =~ /\bprintVars\b/i) { print &getGlobalVars(); next ; } elsif ($each =~ /\bexec\b/i) { ; &setGlobalVars("","tcOP=exec") ; $isBatchProcessing = 1 ; } elsif ($each =~ /\blistTcFilters|printTcFilters\b/i) { ; &setGlobalVars("","tcOP=listtcfilters") ; $isBatchProcessing = 1 ; } elsif ($each =~ /\blist\b/i) { ; &setGlobalVars("","tcOP=list") ; $isBatchProcessing = 1 ; } elsif ($each =~ /\bmark\b/i) { ; &setGlobalVars("","tcOP=mark") ; $isBatchProcessing = 1 ; } elsif ($each =~ /\blistAll\b/i) { ; $SvrTCNamePattern =".*"; &listAll() ; $isBatchProcessing = 0 ; } elsif ($each =~ /customer1/i) { &customer1(); } else { my $str = "\&$each();"; my $rst = eval $str; if ($rst) { print "\`$each\` = \"$rst\"\n"; } else { print "\`$each\` is not a TAF command."; } next; } } else { if ( $each =~ /^\s*(\S+)\s*=\s*(\S+)\s*/ ) { $each =~ /^\s*(\S+)\s*=\s*(\S+)\s*/; my $varName = $1; my $varValue = $2 ; if (($varName !~ /^\s*$/) && ($varValue !~ /^\s*$/)) { $isBatchProcessing = 1; if (&setGlobalVars ("","$varName=$varValue;") == 1 ) { ; } else { $isBatchProcessing = 0; my $rst = &processTC("",$each) ; } } } } } if ($isBatchProcessing == 1) {&tcLoop();} } ################################################################################ # Subroutine Name : process Test Case # Function: wrapper for Test Case management functions # Input Parameters: PropertyOP # Output/Returns : tcName and propertyO/proc ################################################################################ sub processTC { my $tcname; my $cmd=""; shift; my $tcOP= ''; $tcOP = shift if (@_); my $prMsg = '' ; $prMsg= shift if @_; $tcOP =~ /\s*([\w|\d]+)\s*(=)?\s*(\w+)?\s*([;|\/])?(\s*\S+\s*)?/; $tcOP = $1; $tcname = $3; $cmd = $5; $prMsg = $pr2Screen; # if ($cmd =~ /^\s*\.pl\b/) { $cmd = undef ;} # todo temporal fix ######## This is for TCs processing (Batching) if ($tcOP =~ /\blistAll\b/i) { # SvrTCName as a regExp if ($tcname =~ /^\s*$/) { $SvrTCNamePattern =".*";} else { $SvrTCNamePattern = $tcname; } &listAll(); return; } ######## The following are for TC processing if ((defined $tcname) && ($tcname =~ /^.$/) && ($cmd =~ /:[\\|\/]/)) { $tcname = $tcname.$cmd; # handle -s delete=c:\_ts1_ } $tcname = &getTCName($tcname); printf "%-20s %-40s ", "processTC: ", $tcname if $prMsg; # print for webUI 1/2 my $rst; if ( $tcOP =~ /^\s*create/i ) { if ($cmd) { $rst = &createTC("cmd=$cmd",$tcname); } else { $rst = &createTC($tcname); } } elsif ( $tcOP =~ /^\s*exec\b/i ) { $rst = &execTC_($tcname); } elsif ( $tcOP =~ /^\s*mark\b/i ) { $rst = &markTC_($tcname); } elsif ( $tcOP =~ /^\s*execAll/i ) { $rst = &tcLoop(); return $rst; } elsif ( $tcOP =~ /^\s*UpdateWeb/i ) { if (defined $cmd) {;} else { $cmd = 0;} $rst = &updateWeb_($tcname,$cmd); } elsif ( $tcOP =~ /^\s*getWeb_/i ) { $rst = &getWeb_($tcname); } elsif ( $tcOP =~ /^\s*log/i ) { $rst = &logTC($tcname); } elsif ( $tcOP =~ /^\s*detect/i ) { $rst = &detectTC($tcname, $SvrProjName, $SvrDrive); } elsif ( $tcOP =~ /^\s*getLogName/i ) { $rst = &getTCLogFname(&getTCName($tcname)); } elsif ( $tcOP =~ /^\s*listTCFilters/i ) { $rst = &getProperties(&getTCName($tcname) , '.*_all_', 'latest'); } elsif ( $tcOP =~ /^\s*printtcFilters/i ) { $rst = &getProperties(&getTCName($tcname) , '.*_all_', 'latest'); } elsif ( $tcOP =~ /^\s*printResult/i ) { } elsif ( $tcOP =~ /^\s*list|get\b/i ) { $rst = &getProperties(&getTCName($tcname) , 'tcRunResult', 'latest'); # todo !!! Might break other functions !!! # if (defined $cmd) { $rst = &reportTCHistory($tcname); } else { $rst = &reportTC($tcname,"","lastValue") ; } } elsif ( $tcOP =~ /^\s*delete/i ) { $tcOP =~ s/^\s*delete\s*=//g; $tcOP =~ s/\s*$//g; $rst = &deleteTC($tcname); } else { print "<- Test suite \n" if $prMsg; return "_noProcessedTC_"; } printf "%s\n", $rst if $prMsg; # print for webUI 2/2 $rst = sprintf "%-20s %-40s %s", "processTC:", $tcname, $rst ; return $rst; } sub listAll { find(\&recursiveSearchListAll, $SvrDrive); } sub recursiveSearchListAll() { if (($File::Find::name =~ /tc.pl/) && ($File::Find::name =~ /$SvrTCNamePattern/i)) { print "$File::Find::name\n"; } } sub createTS { # Create Testsuite for Testbed my $tsName = "_testsuite_"; $tsName = shift if @_; ####### here if ($SvrProjName ne "_testsuite_") { $tsName = $SvrProjName; } # for backwards compatibility $workingDir = $tsName; if ($workingDir =~ s/_powershell_//i) { my $rst = mkpath $workingDir ; print " --> Create Powershell Testsuite: $workingDir\n"; &generatePowershell_ps1_template(); } else { my $rst = mkpath $workingDir ; print " --> Create Perl Testsuite: $workingDir\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', " Run $testsuite\/$testcase\/tc.hta

    " ); ######################## tc.hta ########################## if ($cmd =~ /Perf/i) { # PerformanceTC &createFile( $tcName.'\\'.$tc_pl, "\$| = 1; print \"1234567.89\\n\"; sleep $sleep; "); } elsif ($cmd =~ /ExpectedFail/i) { # ExpectedFailedTC &createFile( $tcName.'\\'.$tc_pl, "\$| = 1; print \"Expected_f_a_i_l\\n\"; sleep $sleep; "); } elsif ($cmd =~ /Fail/i) { # FailedTC &createFile( $tcName.'\\'.$tc_pl, "\$| = 1; print \"fail\\n\"; sleep $sleep; "); } elsif ($cmd =~ /customTC/i) { # CustomTC $cmd=~ /customTC:\s*(.+)\s*:customTC/; $cmd =$1; $cmd =~ s/_space_/ /; if ($cmd =~ /ps1\s*/) { # Powershell plugin ########### &createFile( $tcName.'\\'.$tc_pl, " use File::Copy;\n\$| = 1; if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"".&getDir($cmd)."\/_tcLogAppend.bak\");} if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"".&getDir($cmd)."\/_tcLogAppend_.bak\");} print `powershell -executionpolicy unrestricted -file $cmd $ps1_args`; # custom TC tc.pl if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"$tcName\/_tcLogAppend.txt\");} if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"$tcName\/_tcLogAppend_.txt\");} " ); ########### } elsif (($cmd =~ /pyanvil/i) &&( $tc_pl =~ /index_pyAnvil\.pl/i)) { # pyAnvil plugin ########### &createFile( $tcName.'\\'.$tc_pl, " use File::Copy;\n\$| = 1; if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"".&getDir($cmd)."\/_tcLogAppend.bak\");} if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"".&getDir($cmd)."\/_tcLogAppend_.bak\");} print `$cmd $ps1_args`; # tc.pl if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"$tcName\/_tcLogAppend.txt\");} if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"$tcName\/_tcLogAppend_.txt\");} " ); ########### } elsif ($cmd =~ /\S+\.pl\s*/) { # perl plugin ########### &createFile( $tcName.'\\'.$tc_pl, " use File::Copy;\n\$| = 1; if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"".&getDir($cmd)."\/_tcLogAppend.bak\");} if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"".&getDir($cmd)."\/_tcLogAppend_.bak\");} print `$cmd`; # c:\\$_TAF\\index.pl if (-e \"".&getDir($cmd)."\/_tcLogAppend.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend.txt\" , \"$tcName\/_tcLogAppend.txt\");} if (-e \"".&getDir($cmd)."\/_tcLogAppend_.txt\" ) {move(\"".&getDir($cmd)."\/_tcLogAppend_.txt\", \"$tcName\/_tcLogAppend_.txt\");} " ); ########### } elsif ( $cmd =~ /taftestcase1/) { ########### &createFile( $tcName.'\\'.$tc_pl, " \$| = 1; \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue1_doit_`; \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=get_property1`; if ( \$rst =~ /propertyValue1/) { print \"pass\\n\";} else {print \"fail\\n\";} \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue0_doit_`; " ); ########### ; } elsif ( $cmd =~ /taftestcase2/) { ########### &createFile( $tcName.'\\'.$tc_pl, " \$| = 1; \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue1A_doit_`; \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=get_property1`; if ( \$rst =~ /propertyValue1A/) { print \"pass\\n\";} else {print \"fail\\n\";} \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue0_doit_`; " ); ########### ; } elsif ( $cmd =~ /taftestcase3/) { ########### &createFile( $tcName.'\\'.$tc_pl, " \$| = 1; \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property2_as_propertyValue2_doit_`; \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=get_property2`; \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;propertyOP=get_property2`; if (( \$rst =~ /testcase1/) && (\$rst =~ /testcase2/) && (\$rst =~ /property2\\s*=\\s*propertyValue2/)) { print \"pass\\n\";} else {print \"fail\\n\";} \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue0_doit_`; " ); ########### ; } elsif ( $cmd =~ /taftestcase4/) { ########### &createFile( $tcName.'\\'.$tc_pl, " \$| = 1; \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property2_as_propertyValue1_doit_`; \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property2_as_propertyValue2_doit_`; \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property2_as_propertyValue2A_doit_`; \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;propertyOP=set_property1_as_propertyValue1A_doit_`; \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;printTcFilters`; if (( \$rst =~ /property1\\s+propertyValue1A/) && (\$rst =~ /property2\\s+propertyValue2A/)) { print \"pass\\n\";} else {print \"fail\\n\";} \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property1_as_propertyValue0_doit_`; \$rst = `c:/_TAF/taf.pl testsuite=_testsuite3_;testcase=_testcase2_;propertyOP=set_property2_as_propertyValue0_doit_`; " ); ########### ; } elsif ( $cmd =~ /powershellTC/) { ########### &createFile( $tcName.'\\'.$tc_pl, " " ); ########### ; } else { ; } } else { &createFile( $tcName.'\\'.$tc_pl, "\$| = 1; print \"pass\\n\"; sleep $sleep; "); } &createPropertyTemplate($tcName); my $tmp =<$tcName\\_tcLogAppend.txt'; print Fout "* This is the content of TC log file\\n"; print Fout "* TC Log can has URL pointed to File Archieve\\n"; print Fout "* TC Log can has URL pointed to Another TC's Log\\n "; print Fout "* TC Log can has URL pointed to TAF\\n"; close Fout; exit; EOF if (($cmd =~ /genLog/i) || ($cmd =~ /addLog/i)) {&appendtoFile( $tcName.'\\'.$tc_pl, $tmp) ; undef $tmp; } $tcName =~ s/\\\\/\\/g; return "is created"; } } sub execTC { my $tcName = &getTCName(@_); my $timeStart = &getDate(); my $rst='' ; if ( -e "$tcName/tc.pl" ) { my $cmd = "$tcName/tc.pl"; $rst = `$cmd`; my $timeEnd= &getDate() ; $rst =~ /(pass|fail|todo|[\d|.]+)$/i; $rst = $1; if ($rst) {;} else {$rst = "null";} # todo Hardcoded if (($rst =~ /Expected_f_a_i_l/i) || ($rst =~ /null/i)) { sleep 10; } $rst =~ s/^\s*0+//g; my $rstStr = sprintf "%20s|%10s|%s", "tcRunResult",$rst , $timeStart ; $rstStr .= "|"; $rstStr .= "$timeEnd"; $rstStr .= "|"; $rstStr .= "0:0:0:0s"; $rstStr .= "|"; if ( $rst =~ /^\s*[\d+|\.]+\s*$/ ) { $rstStr .= "Performance Test ($rst) "; } else { $rstStr .= "Functional Test ($rst) "; } $rstStr .= '|comment2'; &addProperty(&getTCName($tcName), "add=$rstStr"); return $rst; } else { return "tcName: $tcName doesn't exist.\n"; } } sub markTC_ { my $tcName = &getTCName(@_); my $timeStart = &getDate(); my $rst=''; if ( -e "$tcName/$tc_pl" ) { my $cmd = "$tcName/$tc_pl"; $rst = "mark"; # $rst = `$cmd`; my $timeEnd= &getDate(); $rst =~ /(mark|pass|fail|todo|[\d|.]+)$/i; $rst = $1; if ($rst) {;} else {$rst = "null";} $rst =~ s/^\s*0+//g; my $rstStr = sprintf "%20s|%10s|%s", "tcRunResult",$rst , $timeStart; $rstStr .= "|"; $rstStr .= "$timeEnd"; $rstStr .= "|"; $rstStr .= "0:0:0:0s"; $rstStr .= "|"; if ( $rst =~ /^\s*[\d+|\.]+\s*$/ ) { $rstStr .= "Performance Test ($rst) "; } else { $rstStr .= "Functional Test ($rst) "; } $rstStr .= '|comment2'; &addProperty(&getTCName($tcName), "add=$rstStr"); return $rst; } else { return "tcName: $tcName doesn't exist.\n"; } } sub execTC_ { my $tcName = &getTCName(@_); my $timeStart = &getDate(); my $rst=''; if ( -e "$tcName/$tc_pl" ) { my $cmd = "$tcName/$tc_pl"; $rst = `$cmd`; my $timeEnd= &getDate(); $rst =~ /(pass|fail|todo|[\d|.]+)$/i; $rst = $1; if ($rst) {;} else {$rst = "null";} $rst =~ s/^\s*0+//g; my $rstStr = sprintf "%20s|%10s|%s", "tcRunResult",$rst , $timeStart; $rstStr .= "|"; $rstStr .= "$timeEnd"; $rstStr .= "|"; $rstStr .= "0:0:0:0s"; $rstStr .= "|"; if ( $rst =~ /^\s*[\d+|\.]+\s*$/ ) { $rstStr .= "Performance Test ($rst) "; } else { $rstStr .= "Functional Test ($rst) "; } $rstStr .= '|comment2'; &addProperty(&getTCName($tcName), "add=$rstStr"); return $rst; } else { return "tcName: $tcName doesn't exist.\n"; } } sub deleteTC { if ($_[1]) { $SvrProjName = $_[1];} if ($_[2]) { $SvrDrive = $_[2];} my $tcName = &getTCName(@_); #### todo backup deleted TCs. move ($tcName, $tcName."_". &UnixDate( "now", "%m_%d_%Y_%H_%M_%S_%Z" ) ."_backup"); rmtree $tcName; return "$tcName is deleted (saved as *_backup)"; } sub detectTC { if ($_[1]) { $SvrProjName = $_[1];} if ($_[2]) { $SvrDrive = $_[2];} my $tcName = ''; $tcName = &getTCName(@_); if (-e "$tcName\\tc.pl" ) { return "exists"; } else { return 'does not exist';} } sub getTCName { my $SvrProjNameTmp; my $SvrDriveTmp; my $SvrTCNameTmp ; $SvrTCNameTmp = shift if @_; if ($notUsegetTCName==1) { return $SvrTCName;} if ($SvrTCNameTmp) {;} else { $SvrTCNameTmp = $SvrTCName; } if ($SvrProjNameTmp) {;} else { $SvrProjNameTmp = $SvrProjName;} if ($SvrDriveTmp) {;} else { $SvrDriveTmp = $SvrDrive;} if ($SvrTCNameTmp =~ /[a-z]:/i) { return $SvrTCNameTmp; } else { return ($SvrDriveTmp.'/'.$SvrProjNameTmp.'/'.$SvrTCNameTmp) ; } } sub getTCNameStr{ my $SvrTCNameStr = shift; @_ = split /\\|\//, $SvrTCNameStr; pop; } ################################################################################ # Subroutine Name : processProperty # Function: wrapper for property management functions # Input Parameters: PropertyOP # Output/Returns : tcName and propertyOp ################################################################################ sub processProperty { shift; my $tcname = shift; my $propertyOP = shift; my $rst=""; my $prMsg=0; #### PropertyOp String Translation $propertyOP =~ s/^\s*propertyOp\s*=//g; $propertyOP =~ s/^\s*po\s*=//g; $propertyOP =~ s/_doit_//g; if ($propertyOP =~ /^\s*_?set_(.+)_(as|eq)_(.+)/) { $propertyOP = "add_eq_$1_column_$3"; } if ($propertyOP =~ /^\s*_?get_(.+)/) { $propertyOP = "get_$1"; } #### PropertyOp String Translation if (defined $propertyOP) {;} else { $rst = "Warning: wrong format. Correct format is -add=prop:value"; return $rst; } if ($propertyOP =~ /;\s*pr2Screen\s*/) { $prMsg = 1; $propertyOP =~ s/;\s*pr2Screen\s*(=\s*\d*\s*)?//; } if ( $propertyOP =~ /^\s*add/i ) { $rst = &addProperty( &getTCName($tcname), $propertyOP ); } elsif ( $propertyOP =~ /^\s*del/i ) { $rst = &deleteProperty( &getTCName($tcname), $propertyOP ); } elsif ( $propertyOP =~ /^\s*reset/i ) { ; } # copy to a backup and create a property file elsif ( $propertyOP =~ /^\s*modify/i ) { $rst = &modifyProperty( &getTCName($tcname), $propertyOP ); } elsif ( $propertyOP =~ /^\s*get|list/i ) { $propertyOP =~ s/^\s*get_\s*//g; $propertyOP =~ s/^\s*list\s*//g; if ($propertyOP =~ /;/ ) { @_ = split /;/, $propertyOP ; $rst = &getProperties(&getTCName($tcname), $_[0], $_[1]); } else { $rst = &getProperties(&getTCName($tcname), $propertyOP, "value" ); } } elsif ( $propertyOP =~ /^\s*create/i ) { $rst = &createPropertyTemplate($tcname); } elsif ( $propertyOP =~ /^\s*match|filter/i ) { $propertyOP =~ s/^\s*match\s*=//g; $propertyOP =~ /\s*(\S+)\s*[:|;]\s*(\S+)\s*/; $rst = &matchProperty($1, $2, $tcname); } else { $rst = sprintf "ProcessProperty (no match OP) %40s %20s", $tcname, $propertyOP; } if (($rst) && ($rst =~ /^\s*$/)) { $rst = "_noMatchedPropertyOP_";} if ((defined $prMsg) && ($prMsg ==1)) { print $rst;} if ($rst) { return $rst; } else { return "doen't exist"; } } ################################################################################ # Subroutine Name : matchProperties # Function: return true/false # Input Parameters: Property Name in regExp # Output/Returns : True/False ################################################################################ sub matchProperty { # &matchProperty("QAOwner","ywang", "TC_tc1"); my $propertyName = ".*"; my $propertyPattern = ".*"; my %array; my $tcname = "TC_tc1"; $propertyName = shift if (@_); $propertyPattern= shift if (@_); $tcname = shift if (@_); if (&getProperties(&getTCName($tcname)) =~ /info:There is no/ ) { return "False"; } foreach my $each (split /\n/, &getProperties(&getTCName($tcname))) { $each =~ /^\s*(\w+)\s*=\s*(\w+)\s*$/; $array {$1} = $2; } foreach my $each (sort keys %array) { if (($array{$each} =~ /$propertyPattern/) && ( $each =~ /$propertyName/)) { return "True"; } } return 'False'; } ################################################################################ # Subroutine Name : getProperties # Function: return Test Case Property # Input Parameters: Property Name (regExp) (tcName, tcPattern, value) # Output/Returns : Property Value ################################################################################ sub getProperties() { # get TC Property Names (TH:TC Managements) my %array; my $returnValue; my $tcname ; $tcname = shift if @_ ; my $propertyOp ; $propertyOp = shift if @_ ; my $returnType= 'latest'; $returnType = shift if @_ ; $propertyOp =~ s/^\s*add\s*=\s*//ig; $propertyOp =~ s/^\s*_eq_\s*//g; $propertyOp =~ s/\s*_eq_\s*/=/g; $propertyOp =~ s/_column_/:/g; if ($propertyOp =~ /_all_/) { $returnType = "_all_"; $propertyOp =~ s/_all_//g; } if ( -e "$tcname\\thProperty.txt" ) { ; } else { return "info:There is no $_[0]/thProperty.txt here";} open Fin, "$tcname\\thProperty.txt" || die "Can't open file:$!"; while ( $_ = ) { @_= split /\|/, $_; my $propertyName_ = $_[0]; my $propertyValue_ = $_[1]; $propertyName_ =~ s/^\s*//g; $propertyName_ =~ s/\s*$//g; if (($propertyName_ !~ /^\s*$/) && ( $propertyValue_ !~ /^\s*$/)) { if (($propertyName_ =~ /$propertyOp/i) || ( $propertyOp eq '')) { # PropertyPattern Filter if ($returnType =~ /^\s*$/) { $returnValue .= sprintf "%-20s=%s\n",$propertyName_, $propertyValue_; } elsif ($returnType =~ /values/i) { $returnValue .= sprintf "%s\n", $propertyValue_; } elsif ($returnType =~ /_all_/i) { # $returnValue = sprintf "%-20s=%s\n",$propertyName_, $propertyValue_; $propertyValue_ =~ s/^\s*//g; $propertyValue_ =~ s/\s*$//g; $returnValue = sprintf "\t%s\n", $propertyValue_; } elsif ($returnType =~ /history/i) { $returnValue .= sprintf "%-20s=%s\n",$propertyName_, $propertyValue_; } elsif ($returnType =~ /\blatest\b/i) { $returnValue = "$propertyValue_\n"; } elsif ($returnType =~ /\bvalue\b/i) { $returnValue = sprintf "%s\n", $propertyValue_; } } $array{$propertyName_} = $returnValue; } } close Fin; $returnValue = "\n"; if ($returnType =~ /_all_/i) { foreach my $each (sort keys %array) { $returnValue .= sprintf "%20s%s", $each, $array{$each}; } return $returnValue; } else { $returnValue = $array{$propertyOp} ; if ($returnValue ) { $returnValue =~ s/\s*\n\s*$//g; if ($returnValue =~ /^\s*$/) { $returnValue = "_noMatch_";} ; return $returnValue; } else { return ""; } } } ################################################################################ # Subroutine Name : modfyProperty # Function: modify Test Case Property # Input Parameters: Test Case Property Name # Output/Returns : updated c:\TC_*\thProperty.txt # Subroutine Name : # Function: # Input Parameters: # Output/Returns : ################################################################################ sub modifyProperty() { # modify TC Property (TH:TC Managements) my $tcname = $_[0]; my $propertyName = $_[1]; $propertyName =~ s/^\s*modify\s*=\s*//g; $propertyName =~ /(\w+)\s*:\s*(\w+)\s*/; $propertyName = $1; my $propertyValue = $2; my $cmdStr = "delete=$propertyName"; &deleteProperty( $tcname, $cmdStr ); $cmdStr = "add=$propertyName:$propertyValue"; &addProperty( $tcname, $cmdStr ); return "$propertyName is modified to $propertyValue for $tcname"; } ################################################################################ # Subroutine Name : deleteProperty # Function: delete Test Case Property # Input Parameters: Test Case Property Name # Output/Returns : update c:\TC_*\thProperty.txt ################################################################################ sub deleteProperty() { # delete TC Property (TH:TC Managements) my $fname = "$_[0]\\thProperty.txt"; my $fout = $fname; $fout =~ s/\.txt/_Dumpster\.txt/; my $propertyName = $_[1]; if ($propertyName !~ /\s*del\S*\s*=\s*/) { return "Warning: wrong format -del=prop1;pr2Screen";} $propertyName =~ s/^\s*del\S*\s*=\s*//g; $propertyName =~ s/:\s*\S*//; my %array ; open Fin, "$fname"; @_ = ; close Fin; open Fout, ">>$fout"; foreach my $each (@_) { if ( $each =~ /^\s*$propertyName\s*\|/i ) { print Fout "$each"; } } close Fout; open Fout, ">${fname}" || die "Can't open $fname:$!"; foreach my $each (@_) { if ( $each !~ /^\s*$propertyName\s*\|/i ) { print Fout "$each"; } } close Fout; return "$propertyName is deleted from $fname"; } ################################################################################ # Subroutine Name : createPropertyTemplate # Function: # Input Parameters: # Output/Returns : ################################################################################ sub createPropertyTemplate() { # create TC Property File (TH:TC Managements) my $timeStr = getDate(); $timeStr = "|$timeStr|$timeStr|0:0:0:0s|Comment1|Comment2"; my $fname = "@_\\thProperty.txt"; open Fout, ">$fname"; printf Fout "%20s|%10s%s\n", 'tcId','null',$timeStr; printf Fout "%20s|%10s%s\n", 'tcDesc','null',$timeStr; printf Fout "%20s|%10s%s\n", 'tcSPR','null',$timeStr; printf Fout "%20s|%10s%s\n", 'tcSCR','null',$timeStr; printf Fout "%20s|%10s%s\n", 'QA','null',$timeStr; printf Fout "%20s|%10s%s\n", 'modolID','null',$timeStr; printf Fout "%20s|%10s%s\n", 'priority','null',$timeStr; printf Fout "%20s|%10s%s\n", 'openSPR','null',$timeStr; printf Fout "%20s|%10s%s\n", 'tcID','null',$timeStr; printf Fout "%20s|%10s%s\n", 'tcOwner','null',$timeStr; printf Fout "%20s|%10s%s\n", 'tcId','null',$timeStr; printf Fout "%20s|%10s%s\n", 'resultN','null',$timeStr; close Fout; } ################################################################################ # Subroutine Name : addProperty # Function: add Test Case Property # Input Parameters: Test Case Property Name # Output/Returns : updated c:\TC_*\thProperty.txt ################################################################################ sub addProperty() { # add TC Property (TH:TC Managements) my $timeStr = &getDate(); $timeStr = "|$timeStr|$timeStr|0:0:0:0s|comment1|comment2"; my $fname = "$_[0]/thProperty.txt"; my $propertyName = $_[1]; $propertyName =~ s/^\s*add\s*=//g; $propertyName =~ s/^\s*add\s*_eq_\s*//g; open Fout, ">>$fname"; if ($propertyName =~ /\|/) { # for tcRunResult $propertyName =~ /^\s*(\S+)\s*\|\s*(\S+)\s*\|(.+)\s*$/; my $propName = $1; my $propValue = $2; my $propComment = $3; $propValue =~ s/_space_/ /g; $propValue =~ s/_eq_/=/g; $propValue =~ s/_column_/:/g; printf Fout "%20s|%10s|%s\n",$propName, $propValue,$propComment; } else { # $propertyName =~ /^\s*(\S+)_column_(\S+)\s*/; $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 Fout "%20s|%10s%s\n",$propName, $propValue,$timeStr; } } close Fout; return "$propertyName is added to $fname"; } sub getGlobalVars { my $return = < ".$cwd."/index_pyAnvil.pl"; print Fout< \$tcDesc C:/strawberry/perl/bin/perl.exe \$testsuiteHook \$tcId PASS EOF open Fout, ">\$tcScenario"; print Fout \$str; close Fout; my \$cmd = \$pyAnvil."\$tcScenario"; my \$rst = `\$cmd`; foreach my \$each (split /\n/, \$rst) { if ( \$each =~ /^\\s+PASS\\s+/) { \$passFail = "PASS";} elsif (\$each =~ /^\\s+FAIL\\s+/) { \$passFail = "FAIL";} elsif (\$each =~ /^\\s+XML:\\s+(.+)/) { \$logXml = \$1;} elsif (\$each =~ /^\\s+HTML:\\s+(.+)/){ \$logHtml = \$1;} } open Fout, "> \$tcLog_pyAnvil "; print Fout "\$rst\n"; close Fout; print "- > \$tcLog_pyAnvil\n"; print "\$passFail\n"; } ############################ index_pyAnvil.pl ################################### EOF_ close Fout; print " -->".$cwd."/index_pyAnvil.pl\n"; } sub generateGenerateTestsuite { my $cwd = $workingDir; $cwd = shift if @_; open Fout, "> ".$workingDir."/generateTestsuite.pl"; print Fout< ".$cwd."/index.pl"; print Fout<".$cwd."/index.pl\n"; } sub generatePerl_pl_template { my $cmd = $workingDir; if (-e $cmd) {;} else { mkdir $cmd; } open Fout, "> $cmd/index.pl"; my $tsNameTmp = &getRoot($cmd); print Fout<>> 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 \<\ [".$workingDir."/index.pl]\n"; ; #_testsuiteName_: $tsNameTmp #_testdriverName_: $tsDriver } sub generatePowershell_ps1_template { my $cmd = $workingDir; open Fout, "> $cmd/index.ps1"; my $tsNameTmp = &getRoot($cmd); my $tmpWorkingDir = $workingDir; $tmpWorkingDir =~ s/\\/\//g; print Fout< [".$workingDir."/index.ps1]\n"; ; #_testsuiteName_: $tsNameTmp #_testdriverName_: $tsDriver } sub generateTestsuite { # Generating 1. index.pl 2. index.pl + index_pyAnvil.pl my $cmd = $workingDir; $cmd = shift if @_; my $cwd = $cmd; if (-e "$cmd\/index.ps1") { $cmd = $cmd . "\/index.ps1"; #### pre-existing testsuiteHook is index.ps1 &generateIndex_pyAnvil_pl($cwd) ; # --> generate index_pyAnvil.pl &generateIndex_pl ($cwd) ; # --> generate index.pl } elsif (-e "$cmd\/index.pl") { $cmd = $cmd . "\/index.pl";} #### pre-existing testsuiteHook is index.pl else { #### No pre-existing index.pl if ($tsDriver =~ /null/i) { $tsDriver = "$cmd\/index.pl"; } &generatePerl_pl_template(); } ############################################## subroutine Main ########################################### $cmd = shift if @_; my $testsuiteName="_default_testsuiteblas_"; my $testsuitePropertyFName='tsProperty.txt'; my $testDriverName = $cmd; my $tsPropertyStr = "web_ui_title: "; my $tcCtr=1; my $TAF= $SvrDrive ; $testsuiteName = &getRoot_4($cwd); ############ $testsuiteName = &getRoot(&getcwd()); ############ Generate Property file for webUI tc description if ($cmd =~ /\.ps1\s*$/) { $cmd = "powershell -executionpolicy unrestricted -file ". $cmd. " $ps1_args"; } foreach my $each (split "\n", &runPowershell($cmd)) { # get testsuiteName _testsuitename_: (\w+)and _testdrivername_: (\w+) if ($each =~ /_testsuitename_/i) { $each =~ /_testsuitename_\s*:\s*(.+)\s*$/i; $testsuiteName = $1; if ($testsuiteName =~ /\s/) { print "white space in testsuitename\n";exit; }} elsif ($each =~ /_testdrivername_/i) { $each =~ /_testdrivername_\s*:\s*(.+)\s*$/i; $testDriverName = $1; } else { ; } } print<>$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"; $testsuiteName = $testsuiteName; # $cmd = sprintf "tcDelay=0;testsuite=$testsuiteName;list"; $cmd = sprintf "tcDelay=0;testcaseNode=$testcaseNode;testsuite=$testsuiteName;list"; &processTCs("",$cmd); &generateRootIndex(); if ($interact =~ /\by\b/) {system ("C:/Program Files/Internet Explorer/iexplore.exe", "$c/$_TAF/$testsuiteName/index.htm");} print "\n"; 1; } sub help4install { if ( $^O =~ /MSWin32/ ) {; } else { print "TAF supports Win32 ONLY currently.\n"; exit; } &genDriver_taf_pl (); my $help=<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=<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=< 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 ##################### 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 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=.... 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=<$c/$_TAF/taf.pl"; print Fout &prDriver(1); close Fout; print " --> $c/$_TAF/taf.pl\n"; } } sub genDriver { if ($workingDir =~ /\w+:[\/|\\]\s*$/) { print 'Please do *NOT* run perl -MTest::AutomationFramework -e "install" from rootDir. Run it from a directory.'; exit} mkpath $SvrDrive ; if (-e "$c/$_TAF/taf.pl") {;} else { open Fout, ">$c/$_TAF/taf.pl"; print Fout &prDriver(1); close Fout; print " --> $c/$_TAF/taf.pl\n"; } if (-e "$c/$_TAF/taf.bat") {;} else { my $str =<c:\\_TAF\\taf.pl tsFilterDefault=c:\\Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\LBP_Automation_doit_;ps1_args=;ps1_args=-buildpath___c:\\Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\LBP_Automation;scanTestsuite s > e.txt c:\\_TAF\\taf.pl TSHookName=index.ps1;TSHookNameGenerated=index.pl;tcPropertyName=_full_;tsFilterDefault=C:\\Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\LBP_Automation;ps1_args=-buildpath___c:\\Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\LBP_Automation;generateTestsuiteByDesc c:\\_TAF\\taf.pl tsFilterDefault=c:\\Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\LBP_Automation_doit_;ps1_args=-buildpath___c:\\Autobat\\Bat\\QA_Tests\\BATtests\\MVTests\\BAT\\LBP_Automation;scanTestsuites rem copy testsuites taf.pl tsFrom=e.txt;tsTo=ee.txt;copyTS EOF open Fout, "> $c/$_TAF/taf.bat"; print Fout $str; close Fout; print " --> $c/$_TAF/taf.bat\n"; my $cmd = "$c/$_TAF/taf.bat"; system $cmd; } 1; } # install is replaced by genDriver () . it is kept for backwards compatible sub install { &genDriver(); 1; } sub printTestBedProperties { ############ Generate taf Property file for _testsuite3_ open Fout, ">$c/$_TAF/_testsuite3_/tsProperty.txt"; my $str = <$c/$_TAF/_testsuite4_/tsProperty.txt"; $str = <$c/$_TAF/tsProperty.txt"; print Fout< \\\$processTSs, 'processTCs|settings|s=s' => \\\$processTCs, 'processTC|tc=s' => \\\$processTC, 'processProperty|property=s' => \\\$processProperty, 'help' => \\\$help, ); \$TAF = new Test::AutomationFramework; if (\$help) {\$TAF->help();} if (\$prDriver) {\$TAF->prDriver();} if (\$processTSs) { \$TAF->processTSs(\$processTSs);} if (\$processTCs) { \$TAF->processTCs(\$processTCs);} if (\$processProperty) { \$TAF->processProperty(\$processProperty);} if (\$processTC) { \$TAF->processTC(\$processTC);} if (\$scanTestsuites) { \$TAF->scanTestsuites();} foreach \$each (\@ARGV) {\$cmdLine =\$cmdLine.\$each.';'; } \$TAF->processTCs(\$cmdLine) if \$cmdLine; EOF if (@_) { return $driver;} else { print $driver;} } ################################################################################ # Subroutine Name : getDate # Function: get current Datetime # Input Parameters: # Output/Returns : currentDate in the format of 2010-10-02 12:11:22 ################################################################################ sub getDate ( ) { # TH:Generic Functions: get current Time (TH:Generic Functions) my ( $y, $m, $d, $hh, $mm, $ss ) = (localtime)[ 5, 4, 3, 2, 1, 0 ]; $y += 1900; $m++; my $iso_sale_time = sprintf( "%d-%02d-%02d %02d:%02d:%02d", $y, $m, $d, $hh, $mm, $ss ); $iso_sale_time; } ################################################################################ # Subroutine Name : appendtoFile # Function: append text to a file # Input Parameters: 1 Filename 2 String # Output/Returns : New File with the appened text ################################################################################ sub appendtoFile() { # TH:Generic Functions: append to file (TH:Generic Functions) my $fname = $_[0]; open Fout, ">>$fname"; print Fout "$_[1]"; close Fout; } ################################################################################ # Subroutine Name : appendtoFileFile # Function: append file1 to file2 # Input Parameters: 1 Filename 2 String # Output/Returns : New File with the appened text ################################################################################ sub appendtoFileFile() { # TH:Generic Functions: append file to file (TH:Generic Functions) my $fname = $_[0]; my $fnameOUT = $_[1]; open Fin, "$fname" || die "Can't open $fname:$!"; while ($_ = ) { &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 ($_ = ) { $_ =~ /($_TAF.+)[\/|\\]_tcLog\.html/; $record{$1} = $_; } close Fin; $content =~ /($_TAF.+)[\/|\\]_tcLog\.html/; $record{$1} = $content; open Fout, ">$fname_"; foreach my $each (sort keys %record) { print Fout $record{$each} } close Fout; move ($fname_, $fname); } ################################################################################ # Subroutine Name : createFile # Function: create a new file # Input Parameters: 1 Filename 2 String # Output/Returns : New File with the appened text ################################################################################ sub createFile() { # TH:Generic Functions: create to file (TH:Generic Functions) my $fname = $_[0]; $fname =~ s/\\/\//g; if (-e &getDir($fname)) {;} else {mkpath &getDir($fname);} open Fout, ">$fname"; print Fout "$_[1]\n"; close Fout; } ################################################################################ # Subroutine Name : readFile # Function: Read a file # Input Parameters: Filename # Output/Returns : String ################################################################################ sub readFile() { # TH:Generic Functions: read file (TH:Generic Functions) my $fname = $_[0]; if ( -e $fname ) { open Fin, "$fname"; @_ = ; close Fin; return "@_"; } else { return "";} } ################################## STOP TAF Gracefully ############################################ sub detectExitTAFGracefullyLock { if ( -e $exitTAFGracefullyLock) { return "locked"; } else { return "unlocked"; } } sub setExitTAFGracefullyLock { open Fout, ">$exitTAFGracefullyLock"; close Fout; } sub releaseExitTAFGracefullyLock { unlink $exitTAFGracefullyLock; } sub exitTAF { open Fout, ">$exitTAFGracefullyLock"; close Fout; } ################################## concurrency file log ############################################ sub updateWeb_ { my %tsProperty; my $tcname = 'TC_tc1' ; $tcname = shift if @_; my $scrollamount = 0 ; $scrollamount = shift if @_; my $borderwidth = 0 ; $borderwidth = shift if @_; my $borderstyle = 'SOLID' ; $borderstyle = shift if @_; my $movingString = '>' ; $movingString = shift if @_; my $MaxTCExecTime = 10 ; $MaxTCExecTime= shift if @_; @_ = split (/,/ , $scrollamount); if ($_[0]) { $scrollamount = $_[0];} if ($_[1]) { $borderwidth= $_[1];} if ($_[2]) { $borderstyle= $_[2];} if ($movingString =~ /runTC/i) { $movingString = '>'; } if ($movingString =~ /runTS/i) { $movingString = '>>'; } $tcname = &getTCName($tcname); $tcname =~ s/\\/\//g; ############ BEGIN ############# my $fname_ = $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_"; while (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_") { my $mtime = ( stat $fname_)[9]; my $current_time = time; my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; } if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml) { open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml; open Fout, ">".$SvrDrive.'/'.$SvrProjName.'/'.$reportHtml."_"; while ($_ = ) { 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 ($_ = ) { 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 ($_ = ) { if ($_ =~ /$_TAF\/(.+)\/_tcLog.html/) { $_ =~ /$_TAF\/(.+)\/_tcLog.html/; $index{$1} = $_; } } close Fin; } if ( -e $reportFName) {open Fin, $reportFName; while ($_ = ) { 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 ($_ = ) { 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 ($_ = ) { my $tcnameTmp = $tcname; if ( $_ =~ /$tcnameTmp/i) { $_ = $tcHtml; $findMatch ='y'; } # Update Testsuite properties on Test case level if ( $_ =~ /\(Avg Time is\s+(\d+:\d+:\d+)\)/) { $_ =~ s/Avg Time is $1/Avg Time is $testsuiteTotalExecTime/; } print Fout $_; } close Fout; close Fin; move ($SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http."_", $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml_http); } return 1; } sub getWeb_ { my %tsProperty; my $tcname = 'TC_tc1' ; $tcname = shift if @_; my $scrollamount = -1 ; my $borderwidth = -1 ; my $borderStyle = 'SOLID' ; $tcname = &getTCName($tcname); $tcname =~ s/\\/\//g; if (-e $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml) { open Fin, $SvrDrive.'/'.$SvrProjName.'/'.$reportHtml; while ($_ = ) { my $tcnameTmp = $tcname; if ( $_ =~ /$tcnameTmp/i) { $_ =~ /scrollamount=\s*(\d+)\s*/; $scrollamount = $1; $_ =~ /border:RED\s+(\d+)\s*px/; $borderwidth = $1; $_ =~ /\d+\s*px\s+(\w+)\s*"/; $borderStyle= $1; } } close Fin; } return "borderWidth=$borderwidth;scrollAmount=$scrollamount;borderStyle=$borderStyle"; } sub createFile_ { # fname, fileContent, maxTCExecTime my $fname = "e.txt" ; $fname = shift if @_; my $content = "" ; $content = shift if @_; my $MaxTCExecTime = 10 ; $MaxTCExecTime= shift if @_; my $fname_ = $fname."_" ; while (-e $fname_) { my $mtime = ( stat $fname_)[9]; my $current_time = time; my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; } open Fout, ">$fname_" or die $!; print Fout $content; close Fout; move ($fname_, $fname); } sub appendtoFile_ { # fname, fileContent, maxTCExecTime my $fname = "e.txt" ; $fname = shift if @_; my $content = " " ; $content = shift if @_; my $MaxTCExecTime = 10 ; $MaxTCExecTime= shift if @_; my $fname_ = $fname."_" ; while (-e $fname_) { my $mtime = ( stat $fname_)[9]; my $current_time = time; my $diff = $current_time - $mtime; if ($diff > $MaxTCExecTime) { last; } sleep 1; } copy ($fname, $fname_); open Fout, ">>$fname_" or die $!; if ($content) {;} else { $content = "";} print Fout $content; close Fout; move ($fname_, $fname); } sub appendtoFileFile_ { # TH:Generic Functions: append file to file (TH:Generic Functions) my $fname = $_[0]; my $fnameOUT = $_[1]; open Fin, "$fname" || die "Can't open $fname:$!"; my $content; while ($_ = ) { if ($_ !~ /^\s*$/) {$content = $content .$_; } } close Fin; &appendtoFile_($fnameOUT, $content) ; } ################################## concurrency file log ############################################ sub getRoot_4 { my $string = shift; $string =~ s/\w:[\/|\\]//; return $string; } sub getRoot_3 { my $string = shift; @_ = split /\\|\//, $string; if ($#_== 1) { return $_[$#_]; } elsif ($#_ == 2) { my $tmp = $#_ -1; return $_[$tmp].'/'.$_[$#_]; } elsif ($#_ == 3) { my $tmp = $#_ -1; my $tmp1 = $#_ -2; return $_[$tmp1].'/'.$_[$tmp].'/'.$_[$#_]; } elsif ($#_ == 4) { my $tmp = $#_ -1; my $tmp1 = $#_ -2; my $tmp2 = $#_ - 3; return $_[$tmp2].'/'.$_[$tmp1].'/'.$_[$tmp].'/'.$_[$#_]; } elsif ($#_ == 5) { my $tmp = $#_ -1; my $tmp1 = $#_ -2; my $tmp2 = $#_ - 3; my $tmp3 = $#_ - 4; return $_[$tmp3].'/'.$_[$tmp2].'/'.$_[$tmp1].'/'.$_[$tmp].'/'.$_[$#_]; } } sub getRoot { my $string = shift; @_ = split /\\|\//, $string; return $_[$#_]; } sub getDir { my $string = shift; my $root =&getRoot($string); $string =~ s/([\\|\/])?$root//i; return $string; } sub getRoot_1 { my $string = shift; @_ = split /\\|\//, $string; return $_[$#_-1]; } sub prHtml1 { # print index.htm beginnings my $tcPropertyPatternPattern_ = ".*"; ####################### Reset the tcPropertyPatternPattern for index.htm # &readTestSuitProperty (); # Read web_ui_title # my $testsuiteTotalExecTime = &getTestsuiteTotalExecTime ("$SvrDrive/$SvrProjName/index.htm"); my $testsuiteTotalExecTime = &getTestsuiteTotalExecTime ("$SvrDrive/$SvrProjName/$reportHtml1"); &createFile_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml, '' ); &createFile_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml_http, '' ); my $str =<"); my $tmp11= sprintf(""); my $tmp2 = sprintf(""); my $tmp3 = sprintf(""); my $tmp31= sprintf("/"); my $tmp4 = sprintf(" TC Exec Command"); my $tmp5 = sprintf("TC Exec Command"); my $tmp6 = "(sec)"; my $tmp7 = sprintf(" "); my $tmp8 = sprintf(""); my $tmp9 = sprintf(""); my $tmp9A = sprintf(""); my $tmp9B = "Results "; $tmp9B = substr ($tmp9B, 0, $passFailDisplayWidth); my $tmp10 = sprintf(""); my $passFailDisplay = &genPassFailDisplay(""); my $tmp =<

    ${tmp8}$web_ui_title

    ${tmp9A}${tmp9B}${tmp1}Execution $strTmp ${tmp3}Pass${tmp31}${tmp2}Fail ${tmp6} ${tmp7}Exec T ${tmp4} EOF &appendtoFile_ ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml, $tmp); my $tmp1_http = sprintf(" "); my $tmp2_http = sprintf(""); my $tmp3_http = sprintf(""); my $tmp31_http= sprintf("/"); my $tmp4_http = sprintf("TC Exec Command"); my $tmp6_http = "(sec)"; my $tmp7_http = sprintf(""); my $tmp_http =<

    $web_ui_title

    L $strTmp -${tmp3_http}Pass${tmp31_http}${tmp2_http}Fail- ${tmp1_http}Counters Exec T $tmp6_http ${tmp4_http} EOF &appendtoFile_ ($SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml_http, $tmp_http); } sub prHtml2 { # print index.htm endings my $tmp =< EOF &appendtoFile_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml, $tmp ); &appendtoFile_( $SvrDrive.'\\'.$SvrProjName.'\\'.$reportHtml_http, $tmp ); } __END__ TAF Function Summary (Code Name: th.pl as of Sept 27, 2010) ------------------------------------------------------------------------------------------ TH Function Category Function Name Function Description ------------------------------------------------------------------------------------------ TH:TC Managements logIsValid Verify if a log is valid by comparing TC created T and log create T Commented Done TH:TC Managements tcRunningYN get the TC result Pass/Fail Commented Done TH:TC Managements getProperty get TC Property Names Commented Done TH:TC Managements getPropertyValues get TC Property Values Commented Done TH:TC Managements deleteProperty delete TC Property Commented Done TH:TC Managements addProperty add TC Property Commented Done TH:TC Managements modifyProperty modify TC Property Commented Done TH:TC Managements appendPropFile append to TC Property File Commented Done TH:TC Managements createPropFile create TC Property File Commented n/a TH:TC Managements readProperty Read TC Property Commented n/a TH:TC Managements updateTCResultProperty Update TC Property Commented n/a TH:TC Managements genTC Generate a HelloWorld TC Commented Done TH:TC Report Report TC Report Function Commented Done TH:TC Report reportUpdateOnWeb update TC Report on webUI Commented TH:TC Report logExist Determine if a log exists Commented Done TH:TC Execution ReportAvgResponseTime report TC Average Response Time Commented n/a TH:TC Execution lastPassFail get the latest TC Pass/Fail Result Commented Done TH:TC Execution longivityPeriod If the TC in LongivityPeriod Commented TH:WebUI thWebUIUpdate Update the webUI based on thProperty.txt Commented v2 TH:WebUI tcStatusHtmlSync synchrinize the HTML with with TC Result Commented v2 TH:WebUI tcStatusHtml Display the TCStatuse in Html format Commented v2 TH:WebUI rearrangeWebUI Update webUI based on thProperty.txt Commented v2 TH:WebUI tcLog2Web Update TC Log on webUI Commented v2 TH:Concurrency Control tcRunningYNOther get the running TC Status for Concurrency Control. Commented v2 TH:Concurrency Control tcScheduledYNOther get the scheduled TC for Concurrency Control. Commented v2 TH:Concurrency Control tcQueue TC Queue function for Concurrency Control. Commented v2 TH:Concurrency Control tcDeQueue TC deQueue for Concurrency Control Commented v2 TH:Email Notification emailNotification Process the Outlook email Notification Commands Commented v3 TH:Conti. Integration thBuzRule Handle Continuous Integration Commented v3 TH:Assist Functions genTimeStr time format function Commented TH:Assist Functions getIP TH:Generic Functions: get IP of local machine Commented TH:Assist Functions genThProperty generate TH property file Commented TH:Assist Functions printLibraryFun print QTP Library Functions Commented TH:Assist Functions readTestHarnessCmdLine read Test Harness Cmd Line args Commented TH:Assist Functions genQTPInputs generate QTP Input files Commented TH:Assist Functions thPropertyUpdate update TH property Commented TH:Assist Functions prHelp_short Print the short Help Commented todo TH:Assist Functions prHelp print lengthy Help Commented TH:Assist Functions genQTPDriver Generic qtpDriver Commented TH:Assist Functions genQTPLibrary Generate QTP Library Commented TH:Assist Functions genCmd Generate the Test Harness ASP files Commented TH:Generic Functions appendtoFile TH:Generic Functions: append to file Commented Done TH:Generic Functions createFile TH:Generic Functions: create a file Commented Done TH:Generic Functions getDate TH:Generic Functions: get current Time Commented Done TH:Generic Functions reverse TH:Generic Functions: reverse a Associate Array Commented TH:Generic Functions strLen Generic Functon: return Str len Commented TH:Generic Functions decrCtr Decrease Ctr Commented TH:Generic Functions incrCtr Increase Ctr Commented TH:Generic Functions getCtr Get Ctr Commented TH:Generic Functions getCurrentTime TH:Generic Functions: getCurrentTime Commented TH:Generic Functions getHost getHost function done by SZ Team Charlie and David Commented TH:Generic Functions getHostFromIP Get Host done by SZ Team Charlie and David Commented ------------------------------------------------------------------------------------------ =head1 NAME Test::AutomationFramework - Test Automation Framework (TAF) =head2 SYNOPSIS 1. Download and install Test::AutomationFramework from CPAN 2. DOS>perl -MTest::AutomationFramework -e "help" 3. A WebUI is created, which can display and execute, as well as view test case by *ONE* mouse click 3. Modify taf.bat for the automated test suit structures 4. Modify c:\[test_suit]\[test_case]\tc.pl to plug-in the customer test case 5. Execute taf.bat to get the webUI 6. Run test cases, view test result, view test logs with mouse click only. - Enjoy TAF 7. Please email ywangperl@gmail for questions/suggestions/bugs =head2 DESCRIPTION TAF manages automated test cases regarding test setup, test query, test execution and test reult reportings without any programming nor reading user manual. TAF defines a automated test case as [c:]\[test_suite]\[test_case]\tc.pl tc.pl returns Pass|fail|numerical number tc.pl creates tc's log file as [c:]\[test_suite]\[test_case]\tc.pl tc.pl creates test suite's webUI at [c:]\[test_suite]\index.htm =head1 LICENSE This script is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 AUTHOR Yong Wang (ywangperl@gmail.com) =cut; 1; use Test::AutomationFramework; $TAF = new Test::AutomationFramework; foreach $each (@ARGV) { $cmdLine =$cmdLine.$each.';'; } $TAF->processTCs($cmdLine); rem taf.pl -s ts=_test_suit1_;tcop=list rem ts can't be regExp rem taf.pl -s ts=_test_suit1_;tn=*1*;tcop=list rem ts can't be regExp rem rem taf.pl -s ts=_test_suit1_;tcop=exec rem ts can't be regExp rem taf.pl -s ts=_test_suit1_;tn=*1*;tcop=list rem ts can't be regExp rem taf.pl -s printVars rem tas.pl help;printVars;ts=_test_suit3_;tcop=list;list rem tas.pl help;printVars;ts=_test_suit3_;tcop=list;exec rem taf.pl help;printVars;ts=_test_suit3_;tcop=list;list=regExq TODO rem taf.pl help;printVars;ts=_test_suit3_;tcop=list;exec=regExq TODO todo: hardcoded c: taf.pl listAll taf.pl ts=_test_suit1_ -listTC taf.pl ts=_test_suit1_ tc=*test* -listT rem taf.pl listAll=test_suit1;exec rem taf.pl listAll=test_suit1;list taf.pl 'testsuit=_default_testsuite_;create=testcase01/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_1:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase02/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_2:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase03/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_3:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase04/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_4:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase05/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_5:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase06/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_6:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase07/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_7:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase08/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_8:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase09/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_9:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase10/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_10:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase11/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_11:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase12/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_12:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase13/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_13:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase14/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_14:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase15/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_15:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase16/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_16:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase17/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_17:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase18/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_18:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase19/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_19:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase20/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_20:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase21/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_21:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase22/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_22:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase23/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_23:customTC' taf.pl 'testsuit=_default_testsuite_;create=testcase23/overwrite,customTC:c:/tmp/test_default_testsuite_.pl_space_23:customTC' taf.pl testsuit=propertyChangedEvent;list rem taf.pl testsuit=propertyChangedEvent;exec rem taf.pl testsuit=propertyChangedEvent;updateWeb=_testcase2_/1 -- history -- * using the directory recursive for searching testcases * CustomTC:....:CustomTC __END__ ############################ index_pyAnvil.pl ################################### use strict; &execTC($ARGV[0]); sub execTC { my $passFail='FAIL'; my $logHtml; my $logXml ; my $pyAnvil= 'c:/pyAnvil/pyAnvil -s ' ; my $tcDir = "c:/test_pyAnvil/" ; my $testsuiteHook = "index.pl" ; my $tcId = -1 ; $tcId = shift if @_; my $tcDesc = "Testcase $tcId Demo" ; $tcDesc = shift if @_; my $tsDesc = "pyAnvil Testsuite Demo" ; $tsDesc = shift if @_; $testsuiteHook = $tcDir.$testsuiteHook ; my $tcScenario = "_tc.xml" ; $tcScenario = $tcDir."_tc.xml" ; my $tcLog_pyAnvil = "_tcLogAppend_.txt" ; $tcLog_pyAnvil = $tcDir."$tcLog_pyAnvil"; if ($tcId =~ /^\s*$/) { print `$testsuiteHook`; return 0; } my $str=< $tcDesc C:/strawberry/perl/bin/perl.exe $testsuiteHook $tcId PASS EOF open Fout, ">$tcScenario"; print Fout $str; close Fout; my $cmd = $pyAnvil."$tcScenario"; my $rst = `$cmd`; foreach my $each (split /\n/, $rst) { if ( $each =~ /^\s+PASS\s+/) { $passFail = "PASS";} elsif ($each =~ /^\s+FAIL\s+/) { $passFail = "FAIL";} elsif ($each =~ /^\s+XML:\s+(.+)/) { $logXml = $1;} elsif ($each =~ /^\s+HTML:\s+(.+)/) { $logHtml = $1;} } open Fout, "> $tcLog_pyAnvil "; print Fout "$rst\n"; close Fout; print "- > $tcLog_pyAnvil\n"; print "$passFail\n"; } ############################ index_pyAnvil.pl ################################### ##################### index.pl for pyAnvil ############################ my $testsuiteHook = "powershell -executionpolicy unrestricted -file c:/test_pyAnvil/index.ps1 $ps1_args"; if ($ARGV[1]) { print &call_index($ARGV[0], "noExec") ; } elsif ($ARGV[0]) { print &call_index($ARGV[0], "yesExec"); } else { print &call_index(); } sub call_index { my $return ; my $recordCtr=1; if (@_) {;} else {; return `$testsuiteHook`;} my $indexCtr = 9999 ; $indexCtr = shift if @_; my $execYN = 'noExec' ; $execYN = shift if @_; @_ = (split /\n/, `$testsuiteHook`) ; foreach $each (@_) { if (($each) && ($each =~ /^\s*_/)) { $return = $return .$each."\n"; } elsif (($each) && ($each !~ /^\s*_/)) { $return = $return . sprintf "TC [%04s] %s\n",$recordCtr,$each; if (($recordCtr == $indexCtr ) && ( $execYN =~ /noExec/i )) { return "TC [$recordCtr] $each"; } if (($recordCtr == $indexCtr ) && ( $execYN =~ /yesExec/i)) { return `$testsuiteHook $indexCtr ` ; } $recordCtr++; } } if ($return =~ /pass/i) { return 0;} if ($return =~ /fail/i) { return 1;} } ##################### index.pl for pyAnvil ############################ # * add automated TCS for the new functions to the taf.bat # * convert \\ to / for unix port # * multiple tppp filters # * create ps1 testsuite createTS and its test cases # * TAF_Team # * global $index ############# todo: TAF_Team function ############### # * Web Service architecture / CGI / RPC / RubyOnRaid # local run version and /o IIS , support multiple TC Concurrency Control, # Working with new Concurrency Control scheme, TCExecSummary, tcDelay=10 # * Linux porting # * Browser independency # * multi-TS Execution sequentially or concurrently ############# todo: TestSuite Machine independency ###### # * Move/Merge TAF over machine # ** Merge test suite from one machine # ** Merge test suite from multi-machine # ** Move TS from one dir to different dir and regenerate the index*.* # 0. Move the TS to c:\_MachineName\.... # 1. generateAyAnvilTestsuite.pl # 2. Copy c:\_TAF\* to new server # 3. taf testsuite=...;list # 4. Need to copy the AUT to new server # 5. use tsProperty.txt to update # 6. TS titleName # 7. TC directory #Note: ts;list will update all index.html ############################################### ############# MISC ############################ # * Animate Testsuite bulletin. - generateRootIndex ? # * run multi-Testsuites # * GeneratePShellTS # * integrate gerneatePShellTestsuite, # * Notif for the expected failure # * handle unexpected reboot scenario # * win8 installation # * add File::Copy::Recursive dependency in the build process ############################################### ############# todo: MarkTC related Actions ######### # * mark by time # * mark with comments (mouse over comments) # * history mark link to logs/passfail # * mark non-executed TCs #################### Completed Requirements/Bug fixes ########################### # * passFailDisplayWidth is self-adjustable (see todo) -done # * line 1951: **recursive calling** -Done on 09/04/2012-done # * 24 exec, done -done # * Number of TS execution setGlobal(NofExecution = 5) -done # * start/stop gracefully taf.pl exitTAF -done # * 24 continuously, in stead of one test suite -done # * Stop TAF graceffully from webUI -done # * bug: * history is incorrect -done # * Bug 'mark' is counted as a failure -done # * Cleanup the directory with index.ps1 -done (.ps1 takes high priority over *.pl) # * Bug 'L' has characters other than '*' -Ignore (invalid bug) # * Performance improvements -done (performanceMode) # * generateTestsuite will add the tcDesc property -done # * propertyOperation by propertyOp=add=prop1:val1 -done # * propertyOperation by propertyOp=get_prop1:val1 -done # * PropertyFilter for TC operation (e.gl tcDesc = ..) -done # * Search by TCDesc -done by tcProperty # * list should list all TS/TCs -done -handle by scanTestsuites # * Refresh or the historical "*" -done # * testcase=testcase[1,2,3..] work for list. not work for exec -done (it works) # * Bug: pass/fail html is incorrect -done # * 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_ # * 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 -done add=prop:null # * Modify -done add=prop:newValue # * List|get ############ repalced by [set|get]_tcFilter