Revision: 78eb5f07de3a
Author:   Janne Härkönen <[email protected]>
Date:     Wed Feb 22 15:01:14 2012
Log:      first version of testdoc
http://code.google.com/p/robotframework/source/detail?r=78eb5f07de3a

Added:
 /src/robot/testdoc.py
 /src/robot/webcontent/testdoc.html

=======================================
--- /dev/null
+++ /src/robot/testdoc.py       Wed Feb 22 15:01:14 2012
@@ -0,0 +1,155 @@
+#!/usr/bin/env python
+
+#  Copyright 2008-2011 Nokia Siemens Networks Oyj
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+USAGE = """Robot Framework Test Data Documentation Tool
+
+Usage:  testdoc.py [options] data_sources
+
+This tool generates a high level test documentation from a given test data.
+Generated documentation includes the names, documentations and other metadata +of each test suite and test case, as well as the top-level keywords and their
+arguments. Most of the options accepted by this tool have exactly same
+semantics as same options have when executing test cases.
+
+Options:
+  -T --title title       Set the title of the generated documentation.
+                         Underscores in the title are converted to spaces.
+  -N --name name         Set the name of the top level test suite.
+  -D --doc document      Set the document of the top level test suite.
+  -M --metadata name:value *  Set metadata of the top level test suite.
+  -G --settag tag *      Set given tag(s) to all test cases.
+  -t --test name *       Include test cases by name.
+  -s --suite name *      Include test suites by name.
+  -i --include tag *     Include test cases by tags.
+  -e --exclude tag *     Exclude test cases by tags.
+  -h --help              Print this help.
+
+Examples:
+  $ testdoc.py mytestcases.html testdoc.html
+ $ testdoc.py --name smoke_test_plan --include smoke path/to/my_tests/ doc.html
+"""
+import sys
+import os
+import codecs
+
+if 'robot' not in sys.modules:
+    import pythonpathsetter   # running testdoc.py as script
+
+from robot import utils, version
+from robot.running import TestSuite, Keyword
+from robot.conf import RobotSettings
+from robot.parsing import populators
+from robot.reporting.htmlfilewriter import HtmlFileWriter, ModelWriter
+from robot.reporting.jsonwriter import JsonWriter
+
+populators.PROCESS_CURDIR = False
+
+class TestDoc(utils.Application):
+
+    def __init__(self):
+ utils.Application.__init__(self, USAGE, arg_limits=(2,), auto_version=False)
+
+    def main(self, args, title=None, **opts):
+        datasources = args[0:-1]
+        outfile = args[-1]
+        suite = TestSuite(datasources, RobotSettings(opts))
+        self._write_test_doc(suite, outfile, title)
+
+    def _write_test_doc(self, suite, outfile, title):
+        output = codecs.open(outfile, 'w', 'UTF-8')
+        model_writer = TestdocModelWriter(output, suite)
+        HtmlFileWriter(output, model_writer).write('testdoc.html')
+        output.close()
+
+
+class TestdocModelWriter(ModelWriter):
+
+    def __init__(self, output, suite):
+        self._output = output
+        self._suite = suite
+
+    def write(self, line):
+        self._output.write('<script type="text/javascript">' + os.linesep)
+        self._write_data()
+        self._output.write('</script>' + os.linesep)
+
+    def _write_data(self):
+        json = JsonConverter().convert(self._suite)
+        JsonWriter(self._output).write_json('suite = ', json)
+
+
+class JsonConverter(object):
+
+    def convert(self, suite):
+        return self._convert_suite(suite, 's-0')
+
+    def _convert_suite(self, suite, suite_id, index=None):
+ suite_id = suite_id + '-s-%d' % index if index is not None else suite_id
+        return {'name': suite.name,
+                'fullName': suite.longname,
+                'source': suite.source,
+                'doc': suite.doc,
+                'id': suite_id,
+                'metadata': dict(suite.metadata),
+                'numberOfTests': suite.get_test_count(),
+                'suites': self._convert_suites(suite, suite_id),
+                'tests': self._convert_tests(suite, suite_id),
+                'keywords': self._get_suite_keywords(suite, suite_id)
+                }
+
+    def _get_suite_keywords(self, suite, suite_id):
+        kws = []
+        if suite.setup.name:
+ kws.append(self._convert_keyword(suite.setup, suite_id, 0, 'SETUP'))
+        if suite.teardown.name:
+ kws.append(self._convert_keyword(suite.teardown, suite_id, 1, 'TEARDOWN'))
+        return kws
+
+    def _convert_suites(self, suite, suite_id):
+        return [self._convert_suite(suite, suite_id, index)
+                for index, suite in enumerate(suite.suites)]
+
+    def _convert_tests(self, suite, suite_id):
+        return [self._convert_test(test, suite_id, index)
+                for index, test in enumerate(suite.tests)]
+
+    def _convert_test(self, test, suite_id, index):
+        test_id = suite_id + '-t-%d' % index
+        return {'name': test.name,
+                'fullName': test.longname,
+                'id': test_id,
+                'doc': test.doc,
+                'tags': test.tags,
+                'keywords': self._convert_keywords(test, test_id)}
+
+    def _convert_keywords(self, test, test_id):
+            return [self._convert_keyword(k, test_id, index, 'KEYWORD')
+                    for index, k in enumerate(test.keywords)]
+
+    def _convert_keyword(self, kw, test_id, index, type):
+        return {'name': kw.name,
+                'id': test_id + '-k-%d' % index,
+                'arguments': ', '.join(kw.args),
+                'type': type
+                }
+
+
+def testdoc_cli(args):
+    TestDoc().execute_cli(args)
+
+if __name__ == '__main__':
+    testdoc_cli(sys.argv[1:])
+
=======================================
--- /dev/null
+++ /src/robot/webcontent/testdoc.html  Wed Feb 22 15:01:14 2012
@@ -0,0 +1,176 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd";>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<meta http-equiv="Pragma" content="no-cache">
+<meta http-equiv="Expires" content="-1">
+<meta http-equiv="X-UA-Compatible" content="IE=edge">
+<meta name="Generator" content="">
+<link rel="icon" type="image/x-icon" href="data:image/x-icon;base64,AAABAAEAEBAQAAEABAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAAAIAAAAAAAAAAAAAEAAAAAAAAAAAAAAAJEBoACtnfgA5cYYAERsiAEx2lAAbKkQAcazBACZCVwAcM1cAK0ucAAMDBQAnQncASG+FABkoVQAyWmgA6f8SgvH/Ij99+GLyIinyJfn/Yi//KSLzUy9iZogpIld3/4JVVTkid7vyUjNVNVJEAGOZ6Z7pXwAABpmZkRiLAAAGiJZpmGAAAEEt3SXdxAAATC7o/u3EAAC8MRZpjasAAAY1VVVTYAAABKqqqqpAAAAADKqq4AAAAAAAv4sAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMADAADgAwAA4AcAAOAHAADgBwAAwAcAAOAHAADgDwAA8A8AAPg/AAD+fwAA">
+<link rel="stylesheet" type="text/css" href="log.css" media="all">
+<link rel="stylesheet" type="text/css" href="common.css" media="all">
+<link rel="stylesheet" type="text/css" href="print.css" media="print">
+<script type="text/javascript" src="lib/jquery.min.js"></script>
+<script type="text/javascript" src="lib/jquery.tmpl.min.js"></script>
+<script type="text/javascript" src="lib/jsxcompressor.js"></script>
+<script type="text/javascript" src="view.js"></script>
+<script type="text/javascript" src="log.js"></script>
+<!-- JS MODEL --><script type="text/javascript" src="testdata/testdoc.js"></script>
+<title></title>
+</head>
+<body>
+<div id="javascript_disabled">
+  <h1>Opening test suite documentation failed</h1>
+  <ul>
+ <li>Verify that you have <b>JavaScript enabled</b> in your browser.</li> + <li>Make sure you are using a <b>modern enough browser</b>. Firefox 3.5, IE 8, or equivalent is required, newer browsers are recommended.</li> + <li>Check are there messages in your browser's <b>JavaScript error log</b>. Please report the problem if you suspect you have encountered a bug.</li>
+  </ul>
+</div>
+<script type="text/javascript">
+    // Not using jQuery here for speed and to support ancient browsers.
+    document.getElementById('javascript_disabled').style.display = 'none';
+</script>
+
+<div class="header" id="header_div"></div>
+<div id="statistics_container"></div>
+
+<script type="text/javascript">
+$(document).ready(function(){
+    setTitle(window.suite);
+    parseTemplates();
+    addSuite(window.suite);
+    expandSuite(window.suite);
+});
+
+function setTitle(suite) {
+    var givenTitle = suite.title;
+ document.title = givenTitle ? givenTitle : 'Documentation for ' + suite.name;
+    $.tmpl('<h1>' + document.title + '</h1>').appendTo($('body'))
+}
+
+function addSuite(suite) {
+    var root = $.tmpl('suiteTemplate', suite);
+    root.appendTo($('body'));
+    addKeywords(suite);
+    addSuites(suite);
+    addTests(suite);
+}
+
+function addSuites(suite) {
+    $.map(suite.suites, function (s, _) {
+ $.tmpl('suiteTemplate', s).appendTo($('#' + suite.id + '_children'));
+        addKeywords(s);
+        addSuites(s);
+        addTests(s);
+        });
+}
+function addTests(suite) {
+    $.map(suite.tests, function (test, _) {
+ $.tmpl('testTemplate', test).appendTo($('#' + suite.id + '_children'));
+        addKeywords(test);
+        });
+}
+
+function addKeywords(parent) {
+    $.map(parent.keywords, function (kw, _) {
+ $.tmpl('keywordTemplate', kw).appendTo($('#' + parent.id + '_children'));
+    });
+}
+</script>
+
+<script type="text/x-jquery-tmpl" id="suiteTemplate">
+  <div id="${id}" class="suite">
+    <div id="${id}_elementheader" class="elementheader"
+         onclick="toggleSuite('${id}');" title="${fullName}">
+      <div id="${id}_foldingbutton" class="foldingbutton">+</div>
+      <span class="not_run">TEST&nbsp;SUITE:</span>
+      <span class="name">${name}</span>
+        <a class="expandall" href="javascript:expandAllChildren('${id}')"
+           onclick="stopPropagation(event);">Expand All</a>
+    </div>
+    <div id="${id}_children" style="display: none;">
+      <table class="metadata">
+        <tr>
+          <th>Full Name:</th>
+          <td>${fullName}</td>
+        </tr>
+        {{if doc}}
+        <tr>
+          <th>Documentation:</th>
+          <td>{{html doc}}</td>
+        </tr>
+        {{/if}}
+        {{each metadata}}
+        <tr>
+          <th>${$value[0]}:</th>
+          <td>{{html $value[1]}}</td>
+        </tr>
+        {{/each}}
+        {{if source}}
+        <tr>
+          <th>Source:</th>
+          {{if relativeSource}}
+          <td><a href="${relativeSource}">${source}</a></td>
+          {{else}}
+          <td>${source}</td>
+          {{/if}}
+        </tr>
+        {{/if}}
+        <tr>
+          <th>Number of Tests:</th>
+          <td>${numberOfTests}</td>
+        </tr>
+      </table>
+    </div>
+  </div>
+</script>
+
+<script type="text/x-jquery-tmpl" id="testTemplate">
+  <div id="${id}" class="test">
+    <div id="${id}_elementheader" onclick="toggleTest('${id}');"
+         class="elementheader" title="${fullName}">
+      <div id="${id}_foldingbutton" class="foldingbutton">+</div>
+      <span class="not_run">TEST&nbsp;CASE: </span>
+      <span class="name">${name}</span>
+        <a class="expandall" href="javascript:expandAllChildren('${id}')"
+           onclick="stopPropagation(event);">Expand All</a>
+    </div>
+    <div id="${id}_children" style="display: none;">
+      <table class="metadata">
+        <tr>
+          <th>Full Name:</th>
+          <td>${fullName}</td>
+        </tr>
+        {{if doc}}
+        <tr>
+          <th>Documentation:</th>
+          <td>{{html doc}}</td>
+        </tr>
+        {{/if}}
+        <tr>
+            <th>Tags:</th>
+            <td>${tags}</td>
+        </tr>
+        {{if timeout}}
+        <tr>
+          <th>Timeout:</th>
+          <td>${timeout}</td>
+        </tr>
+        {{/if}}
+      </table>
+    </div>
+  </div>
+</script>
+
+<script type="text/x-jquery-tmpl" id="keywordTemplate">
+  <div id="${id}" class="keyword">
+      <span class="not_run">${type}: </span>
+      <span class="name">${name}</span>
+      <span class="arg">${arguments}</span>
+  </div>
+</script>
+
+
+</body>
+</html>

Reply via email to