MantisBT - TestLink
View Issue Details
0000899TestLinkReportspublic2007-06-12 19:342015-05-01 07:47
kencruickshank 
fman 
normalfeature requestalways
closedfixed 
1.7.0 RC 2 
1.9.14 (2015 Q3) 
TBD
0000899: Improved format of printed Test Specification
The report formatting can be improved mainly to make the format more compatibel with Word.

Changes made are:

1. Output a style to allow teh browser to print [page breakss (HTML display ignore the style)

2. Use a nested set of h1, h2 etc instead of having all headers h1. Tis allows word to outline the document

3. change 0018 use margin-left and not padding-left as margin-left is honoured by msword and browsers for the tabel of contents

4. Use the first name last name instead of log on name when outpuuting the iuser name on reports

5. Use nested tables to force the browser to align the test tables.

The changes are all made in print.inc.php, full code is attached.

Also requires a change to users.inc.php

/* kjc change 017 return a friendly name */
function getFriendlyUserName(&$db,$id_user)
{
    $username = '';
    if(intval($id_user) > 0 )
    {
        $username = lang_get('Unknown');
        $uInfo = getUserById($db,$id_user);
        if ($uInfo)
            $username = $uInfo[0]['first'] . " " . $uInfo[0]['last'];
    }
    return $username;
}

<?php
/**
 * TestLink Open Source Project - http://testlink.sourceforge.net/ [^]
 *
 * @filesource $RCSfile: print.inc.php,v $
 * @version $Revision: 1.29 $
 * @modified $Date: 2007/05/10 19:55:43 $ by $Author: schlundus $
 *
 * @author Martin Havlat <havlat@users.sourceforge.net>
 *
 * Functions for support printing of documents.
 *
 * 20070509 - franciscom
 * changes in renderTestSpecTreeForPrinting() interface
 *
 * 20070106 - franciscom
 * 1. remove of some magic numbers
 *
 */

/**
 * print HTML header
 * Standard: HTML 4.01 trans (because is more flexible to bugs in user data)
 */
function printHeader($title, $base_href, $cssTemplate = TL_DOC_BASIC_CSS)
{
    $output = "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>\n";
    $output .= "<html>\n<head>\n";
    $output .= '<meta http-equiv="Content-Type" content="text/html; charset='.TL_TPL_CHARSET.'" />';
    $output .= '<title>' . htmlspecialchars($title). "</title>\n";
    $output .= '<link type="text/css" rel="stylesheet" href="' . $base_href . $cssTemplate . '" />';
    $output .= '<style type="text/css" media="print">.notprintable { display:none;}</style>';
    $output .= "\n</head>\n<body>\n";

    return $output;
}

/**
  print HTML - initial page of document
*/
function printFirstPage(&$db,$title, $prodName, $prodNotes, $userID)
{
    $g_date_format = config_get('date_format');
    $prodName = htmlspecialchars($prodName);
    
    /*kjc change 017 use teh first last name instead of teh log on name */
    $author = htmlspecialchars(getFriendlyUserName($db,$userID));
        
    $title = htmlspecialchars($title);
    
    $output = '<div>';
    $output .= '<div class="groupBtn" style="text-align:right"><input class="notprintable" type="button" name="print" value="'.lang_get('btn_print').'" onclick="javascript: print();" style="margin-left:2px;" /></div>';

    $output .= '<div class="pageheader">'. $prodName ."</div>\n";
    
    if (TL_DOC_COMPANY != '' || TL_DOC_COMPANY_LOGO != '' )
    {
        $output .= '
<center><table class="company">';

          if (TL_DOC_COMPANY != '' )
          {
            $output .= '<tr><td id="company_name">'. htmlspecialchars(TL_DOC_COMPANY) ."</td></tr>";
        }
        $output .= '<tr><td/></tr>';
          
          if (TL_DOC_COMPANY_LOGO != '' )
        {
            $output .= '<tr><td id="company_logo">'.
                    str_replace('%BASE_HREF%',$_SESSION['basehref'],TL_DOC_COMPANY_LOGO) ."</td></tr>";
        }
        $output .= "</table></center>\n";
    }
    
    $output .= "</div>\n";

    $output .= '<h1 id="doctitle">'.$title."</h1>\n";
    $output .= '<div id="summary">' .
                 '<p id="prodname">'. lang_get('product').": " . $prodName . "

\n";
    if (strlen($prodNotes))
        $output .= '<p id="prodnotes">'. $prodNotes . "

\n";
               
    $output .= '<p id="author">' . lang_get('author').": " . $author . "

\n" .
                 '<p id="printedby">' . lang_get('printed_by_TestLink_on')." ".
                 strftime($g_date_format, time()) . "

</div>\n";

    if (TL_DOC_COPYRIGHT != '')
        $output .= '<div class="pagefooter" id="copyright">'.htmlspecialchars(TL_DOC_COPYRIGHT)."</div>\n";
    if (TL_DOC_CONFIDENT != '')
        $output .= '<div class="pagefooter" id="confidential">'.htmlspecialchars(TL_DOC_CONFIDENT)."</div>\n";

    /* kjc change 0003 output a style so when printing we may get a page break */
        $output .= "<br clear=all style='page-break-before:always'/>";
        $output .= " ";
        
    return $output;
}


/*
  function: renderTestSpecTreeForPrinting

  args :
  
        [$tplan_id]
        
  returns:
  
  rev :
       20070509 - franciscom - added $tplan_id in order to refactor and
                               add contribution BUGID

*/
function renderTestSpecTreeForPrinting(&$db,&$printingOptions,&$node,$tocPrefix,$tcCnt,$level,$tplan_id=0)
{
  $tree_mgr = new tree($db);
  $map_id_descr = array_flip($tree_mgr->get_available_node_types());
  
    $code = null;
    $bCloseTOC = 0;
    if (isset($node['node_type_id']))
    {
          $verbose_node_type = $map_id_descr[$node['node_type_id']];
        switch($verbose_node_type)
        {
            case 'testproject':
                $code .= renderProjectNodeForPrinting($db,$printingOptions,$printingOptions['title'],$node);
                break;
                    
            case 'testsuite':
                if (!is_null($tocPrefix))
                    $tocPrefix .= ".";
                $tocPrefix .= $tcCnt;
                $code .= renderTestSuiteNodeForPrinting($db,$printingOptions,$node,$tocPrefix,$level);
                break;
            
            case 'testcase':
                $code .= renderTestCaseForPrinting($db,$printingOptions,$node,$level,$tplan_id);
                break;
        }
    }
    if (isset($node['childNodes']) && $node['childNodes'])
    {
        $childNodes = $node['childNodes'];
        $tsCnt = 0;
    $children_qty=sizeof($childNodes);
        for($i = 0;$i <$children_qty ;$i++)
        {
            $current = $childNodes[$i];
            if(is_null($current))
                continue;
            
            if (isset($current['node_type_id']) && $map_id_descr[$current['node_type_id']] == 'testsuite')
                $tsCnt++;

            /* kjc change 0017 use tables to force better alignment particularly with in word */
            $code .= "<table width='98%' style='border: 0px; border-collapse:collapse;'><tr><td style='border: 0px; border-collapse:collapse;'>";
            $code .= renderTestSpecTreeForPrinting($db,$printingOptions,$current,$tocPrefix,$tsCnt,$level+1);
            $code .= "</td></tr></table>";
        }
    }
    if (isset($node['node_type_id']) && $map_id_descr[$node['node_type_id']] == 'testproject')
    {
        if ($printingOptions['toc'])
        {
            $printingOptions['tocCode'] .= '</div><hr />';

            /* kjc change 0003 output a style so when printing we may get a page break */
            $printingOptions['tocCode'] .= "<br clear=all style='page-break-before:always'>";
            $printingOptions['tocCode'] .= " ";

            $code = str_replace("{{INSERT_TOC}}",$printingOptions['tocCode'],$code);
        }
        $code .= "</body></html>";
    }
        
    return $code;
}

/*
  function:

  args :
  
  returns:

  rev :
       20070509 - franciscom - added Contribution
       
*/
function renderTestCaseForPrinting(&$db,&$printingOptions,&$node,$level,$tplan_id=0)
{
     $id = $node['id'];
    $name = htmlspecialchars($node['name']);
    
    $code = null;
  $tc_mgr = null;
  $tcInfo = null;
  
  $versionID = isset($node['tcversion_id']) ? $node['tcversion_id'] : TC_LATEST_VERSION;
        
    if( $printingOptions['body'] || $printingOptions['summary'] ||
        $printingOptions['author'] )
    {
        $tc_mgr = new testcase($db);
    $tcInfo = $tc_mgr->get_by_id($id,$versionID);

      if ($tcInfo)
        {
        $tcInfo=$tcInfo[0];
      }
    
    }

    
    if ($printingOptions['toc'])
    {
        /* kjc change 0018 use margin-left and not padding-left as margin-left is honoured by msword and browsers */
      $printingOptions['tocCode'] .= '<p style="margin-left: '.(15*$level).'px;">#tc' . $id . '

';
        $code .= "<a name='tc" . $id . "'></a>";
    }
     $code .= "<div class=\"tc\"><table class=\"tc\" width=\"90%\">";
     $code .= "<tr><th colspan=\"2\">".lang_get('test_case')." " . $id . ": " .
                 $name . "</th></tr>";
    

  if ($printingOptions['body'] || $printingOptions['summary'])
    {
        if ($tcInfo)
        {
            //kjc change 004 output the test case version
            $code .= "<tr><td>".lang_get('version').": " . $tcInfo['version'] . "</td></tr>";
            //kjc

            if ($printingOptions['summary'])
                $code .= "<tr><td colspan=\"2\">".lang_get('summary').": " . $tcInfo['summary'] . "</td></tr>";
            if ($printingOptions['body'])
            {
                //kjc change 005 output custom fields
                $tc = new testcase($db);
                $code .= "<tr><td>";
                $code .= $tc->html_table_of_custom_field_values($id) ;
                $code .= "</td></tr>";
                // kjc

                   $code .= "<tr><td colspan=\"2\">".lang_get('steps').":
" . $tcInfo['steps'] . "</td></tr>";
                   $code .= "<tr><td colspan=\"2\">".lang_get('expected_results').":
" . $tcInfo['expected_results'] . "</td></tr>";
            }
            if ($printingOptions['passfail'])
            {
                $code .= "<tr><td width=\"20%\" valign=\"top\">".lang_get('passfail').":</td><td>".
                lang_get('testnotes')."
:


</td></tr>";
            }
        }
    }

  if ($printingOptions['author'])
  {
        /*kjc change 017 use teh first last name instead of teh log on name */
     $authorName = getFriendlyUserName($db, $tcInfo['author_id']);
     $code .= '<tr><td colspan="2">' . lang_get("author") . " " . $authorName . "</td></tr>";
  }

    $code .= "</table></div>";

  if( !is_null($tc_mgr) )
    {
      unset($tc_mgr);
    }
    
    
    return $code;
}

function renderProjectNodeForPrinting(&$db,&$printingOptions,$title,&$node)
{
    $stitle = lang_get('title_test_spec');
    if (strlen($title))
        $stitle .= " - " . $title;
    
    $my_userID = isset($_SESSION['userID']) ? intval($_SESSION['userID']) : null;

    $tproject = new testproject($db);
    $projectData = $tproject->get_by_id($node['id']);
    unset($tproject);
    $code = printHeader($stitle,$_SESSION['basehref']);
    $code .= printFirstPage($db,$stitle, $projectData['name'], $projectData['notes'], $my_userID);

    $printingOptions['toc_numbers'][1] = 0;
    if ($printingOptions['toc'])
    {
        $printingOptions['tocCode'] = '<div class="toc"><h2>'.lang_get('title_toc').'</h2>';
        $code .= "{{INSERT_TOC}}";
    }
    
    return $code;
}


function renderTestSuiteNodeForPrinting(&$db,&$printingOptions,&$node,$tocPrefix,$level)
{
    $code = null;
    $name = isset($node['name']) ? htmlspecialchars($node['name']) : '';
    if ($printingOptions['toc'])
    {
        /* kjc change 0018 use margin-left and not padding-left as margin-left is honoured by msword and browsers */
         $printingOptions['tocCode'] .= '<p style="margin-left: '.(10*$level).'px;">#cat' . $node['id'] . '

';
        $code .= "<a name='cat{$node['id']}'></a>";
    }
    /* KJC change 014 output a nested h set */
     $code .= "<h" . $level . ">{$tocPrefix} ". lang_get('test_suite') ." {$name}</h" . $level . ">";
                         
    if ($printingOptions['header'])
      {
        $tsuite = new testsuite($db);
        $tInfo = $tsuite->get_by_id($node['id']);
        unset($tsuite);
        $code .= "<h2>{$tocPrefix}.0 ". lang_get('details').
                 "</h2><div>{$tInfo['details']}</div>
";
     }
    
    return $code;
}
?>
No tags attached.
Issue History
2007-06-12 19:34kencruickshankNew Issue
2007-11-18 10:27mhavlatNote Added: 0002680
2007-11-18 10:27mhavlatStatusnew => acknowledged
2007-11-18 10:27mhavlatCategoryNew Feature => Test Specification
2007-11-18 10:27mhavlatSummaryImproved Report formats => Improved format of printed Test Specification
2009-03-17 15:54mhavlatAssigned To => mhavlat
2009-03-17 15:54mhavlatCategoryTest Specification => Reports, Metrics, Export and Print
2009-03-17 15:54mhavlatAdditional Information Updated
2010-02-28 22:25mhavlatAssigned Tomhavlat =>
2015-04-26 16:00Mr.BricodageRelationship addedchild of 0007083
2015-04-26 16:00Mr.BricodageNote Added: 0023165
2015-05-01 07:47fmanQA Team - Task Workflow Status => TBD
2015-05-01 07:47fmanStatusacknowledged => closed
2015-05-01 07:47fmanAssigned To => fman
2015-05-01 07:47fmanResolutionopen => fixed
2015-05-01 07:47fmanFixed in Version => 1.9.14 (2015 Q3)
2015-05-03 15:24Mr.BricodageRelationship deletedchild of 0007083

Notes
(0002680)
mhavlat   
2007-11-18 10:27   
The format need update.
(0023165)
Mr.Bricodage   
2015-04-26 16:00   
Export Test Spec is now compatible with Word and work great