From c61d1720d1cf30cb37549ad1d9e0ee4c2feb0519 Mon Sep 17 00:00:00 2001 From: Luis Araujo <luis.araujo@collabora.co.uk> Date: Fri, 30 Nov 2018 17:39:43 +0800 Subject: [PATCH] Add option to create index page This commit adds the --index-page option to create an index page for the test cases. Signed-off-by: Luis Araujo <luis.araujo@collabora.co.uk> --- renderer/render-test-case | 15 +++- renderer/renderer.py | 50 ++++++++++++-- renderer/templates/index.html | 111 ++++++------------------------ renderer/templates/test_case.html | 108 +++++++++++++++++++++++++++++ renderer/tests.py | 26 +++---- 5 files changed, 199 insertions(+), 111 deletions(-) create mode 100644 renderer/templates/test_case.html diff --git a/renderer/render-test-case b/renderer/render-test-case index 3748f8a..d76150a 100755 --- a/renderer/render-test-case +++ b/renderer/render-test-case @@ -25,7 +25,7 @@ import os import shutil from argparse import ArgumentParser -from renderer import generate_test_case +from renderer import generate_test_case_page, generate_index_page def copy_files(directory, dirname, msg): @@ -48,10 +48,13 @@ if '__main__' == __name__: cli_parser = ArgumentParser(description="render-test-case") cli_parser.add_argument('-d', '--test-case-dir', help="Directory path for generated test cases") + cli_parser.add_argument('-i', '--index-page', action='store_true', + help="Create index page") cli_parser.add_argument('yaml_files', help="YAML file or files directory") args = cli_parser.parse_args() + index_files = [] directory = os.getcwd() if args.test_case_dir: directory = args.test_case_dir @@ -64,17 +67,23 @@ if '__main__' == __name__: exit(1) if os.path.isfile(args.yaml_files): - generate_test_case(args.yaml_files, directory) + generate_test_case_page(args.yaml_files, directory) + index_files.append(args.yaml_files) else: c = 0 for root, _, files in os.walk(args.yaml_files): for f in files: tc_file = os.path.join(root, f) if os.path.isfile(tc_file): - generate_test_case(tc_file, directory) + generate_test_case_page(tc_file, directory) + if args.index_page: + index_files.append(tc_file) c += 1 print("Total of test cases processed:", c) # Copy CSS and images directory copy_files(directory, 'css/', "Copying css style to") copy_files(directory, 'images/', "Copying images to") + + if index_files: + generate_index_page(index_files, directory) diff --git a/renderer/renderer.py b/renderer/renderer.py index e5bbf1f..8c6ca3b 100644 --- a/renderer/renderer.py +++ b/renderer/renderer.py @@ -159,7 +159,7 @@ def get_template_values(testcase_data): return template_values -def generate_test_case(tc_file, directory='.', return_out=False): +def generate_test_case_page(tc_file, directory='.', return_out=False): try: with open(tc_file) as testcase: tc_data = yaml.safe_load(testcase) @@ -179,7 +179,7 @@ def generate_test_case(tc_file, directory='.', return_out=False): env = Environment(loader=FileSystemLoader([TEMPLATE_DIR])) # Get template from environment and render it. - data = env.get_template('templates/index.html').render(get_template_values(tc_data)) + data = env.get_template('templates/test_case.html').render(get_template_values(tc_data)) # Return the data if return_out=True if return_out: @@ -187,5 +187,47 @@ def generate_test_case(tc_file, directory='.', return_out=False): filename = os.path.splitext(os.path.basename(tc_file))[0] + ".html" print("Generating test case page", filename) - with open(os.path.join(directory, filename), 'w') as html_file: - html_file.write(data) + with open(os.path.join(directory, filename), 'w') as test_case_html_file: + test_case_html_file.write(data) + +def generate_index_page(tc_files, directory='.'): + # Sort alphabetically in the index. + tc_files.sort() + # The `index` list is the main structure, each element has the form: + # (name, description, exec-type, priority, priority_color, filename) + index = [] + # `counts` is used to collect stats. + counts = { 'automated' : 0, 'manual' : 0, 'all' : 0, + 'low' : 0, 'medium' : 0, 'high' : 0, 'critical' : 0, + 'total' : 0 } + + print("Generating index page ...") + for f in tc_files: + filename = os.path.splitext(os.path.basename(f))[0] + try: + with open(f) as testcase: + tc_data = yaml.safe_load(testcase) + except yaml.scanner.ScannerError as e: + print("yaml format error:", e) + exit(1) + + priority = tc_data['metadata']['priority'] + exec_type = tc_data['metadata']['exec-type'] + index.append((tc_data['metadata']['name'], + tc_data['metadata']['description'], + exec_type, priority, priority_color(priority), filename)) + + # Collect some stats to show in the page. + counts[exec_type] = counts.copy()[exec_type] + 1 + counts[priority] = counts.copy()[priority] + 1 + counts['total'] = counts.copy()['total'] + 1 + + env = Environment(loader=FileSystemLoader([TEMPLATE_DIR])) + # Get template from environment and render it. + template_values = { 'index_files': index, 'counts': counts } + data = env.get_template('templates/index.html').render(template_values) + + index_path = os.path.join(directory, 'index.html') + with open(index_path, 'w') as index_html_file: + index_html_file.write(data) + print("Index page created at", index_path) diff --git a/renderer/templates/index.html b/renderer/templates/index.html index 6cf942f..b23fa91 100644 --- a/renderer/templates/index.html +++ b/renderer/templates/index.html @@ -4,105 +4,34 @@ <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link href="css/bootstrap.min.css" rel="stylesheet"> - <title>{{ name }}</title> + <title>Test Cases</title> </head> <body> - {% import 'templates/macros.html' as macros %} <main role="main" class="container" style="margin-top: 40px; margin-bottom: 40px"> - <h2>{{ name }} <small class="text-muted">{{ exec_type }}</small></h2> - <h3><span class="badge badge-{{ priority_color }}">{{ priority }}</span></h3> - - <div class="card" style="margin-top: 20px"> - <div class="card-body"> - <dl class="row"> - <dt class="col-sm-3">Image Type:</dt> - <dd class="col-sm-9">{{ image_type }}</dd> - <dt class="col-sm-3">Image Architecture:</dt> - <dd class="col-sm-9">{{ image_arch }}</dd> - <dt class="col-sm-3">Type:</dt> - <dd class="col-sm-9">{{ type }}</dd> - </dl> - - <h4>Description</h4> - <p>{{ description }}</p> - - {% if resources %} - <hr /> - <h4>Resources</h4> - <ul> - {% for resource in resources %} - <li>{{ resource|e }}</li> - {% endfor %} - </ul> - {% endif %} - - {% if pre_conditions or pkgname or packages_list or libname %} - <hr /> - <h4>Pre Conditions</h4> - <ol> - {% if pkgname %}{{ macros.ostree_preconditions(pkgname) }}{% endif %} - {% if packages_list %}{{ macros.install_packages(packages_list) }}{% endif %} - {% if libname %}{{ macros.modules_preconditions(libname) }}{% endif %} - {% for comment, command, output, _, link in pre_conditions %} - {% if comment %}<li class="mb-sm-2">{{ comment|e }}</li>{% endif %} - {% if command %}<p><kbd>{{ command|e }}</kbd></p>{% endif %} - {% if link %}<p><a href="{{ link }}">{{ link }}</a></p>{% endif %} - {% if output %}{% for l in output %}<p class="mb-sm-0 pl-sm-3"><samp>{{ l|e }}</samp></p>{% endfor %}{% endif %} - {% endfor %} - </ol> - {% endif %} - + <h2>Test Cases</h2> <hr /> - <h4>Execution Steps</h4> - <ol> - {% for comment, command, output, _, link in run_steps %} - {% if comment %}<li class="mb-sm-2">{{ comment|e }}</li>{% endif %} - {% if command %}<p><kbd>{{ command|e }}</kbd></p>{% endif %} - {% if output %}{% for l in output %}<p class="mb-sm-0 pl-sm-3"><samp>{{ l|e }}</samp></p>{% endfor %}{% endif %} - {% endfor %} - </ol> - <hr /> - <h4>Expected</h4> - {% for comment, command, output, image, link in expected %} - {% if comment %}<p class="mt-sm-3">{{ comment|e }}</p>{% endif %} - {% if command %}<p><kbd>{{ command|e }}</kbd></p>{% endif %} - {% if output %}{% for l in output %}<p class="mb-sm-0 pl-sm-3"><samp>{{ l|e }}</samp></p>{% endfor %}{% endif %} - {% if image %}<img src="images/{{ image }}" class="img-fluid">{% endif %} - {% if link %}<p><a href="{{ link }}">{{ link }}</a></p>{% endif %} - {% endfor %} - - {% if post_conditions %} - <hr /> - <h4>Post Conditions</h4> - <ol> - {% for comment, command, output, _, link in post_conditions %} - {% if comment %}<li class="mb-sm-2">{{ comment|e }}</li>{% endif %} - {% if command %}<p><kbd>{{ command|e }}</kbd></p>{% endif %} - {% if output %}{% for l in output %}<p class="mb-sm-0 pl-sm-3"><samp>{{ l|e }}</samp></p>{% endfor %}{% endif %} - {% endfor %} - </ol> - {% endif %} + <ul class="list-inline"> + <li class="list-inline-item"><h6><strong>Type:</strong> <em>{{ counts.automated }} automated / {{ counts.manual }} manual / {{ counts.all }} both</em> + </li> + <li class="list-inline-item"><strong>Priority:</strong> <em>{{ counts.low }} low / {{ counts.medium }} medium / {{ counts.high }} high / {{ counts.critical }} critical</em> + </li> + <li class="list-inline-item"><strong>Total:</strong> <em>{{ counts.total }}</em> + </li> + </ul> - </div> + <div class="list-group"> + {% for name, description, exec_type, priority, priority_color, filename in index_files %} + <a href="{{ filename }}.html" class="list-group-item list-group-item-action flex-column align-items-start"> + <div class="d-flex w-100 justify-content-between"> + <h5 class="mb-1"><strong>{{ name }}</strong> <small>{{ exec_type }}</small></h5> + </div> + <p class="mb-1">{{ description }}</p> + <big><span class="badge badge-{{ priority_color }}">{{ priority }}</span></big> + </a> + {% endfor %} </div> - {% if notes %} - <div class="card" style="margin-top: 30px"> - <div class="card-body"> - <h4>Notes</h4> - <ul> - {% for comment, command, output, _, link in notes %} - {% if comment %}<li class="mb-sm-2">{{ comment|e }}</li>{% endif %} - {% if command %}<p><kbd>{{ command|e }}</kbd></p>{% endif %} - {% if output %}{% for l in output %}<p class="mb-sm-0 pl-sm-3"><samp>{{ l|e }}</samp></p>{% endfor %}{% endif %} - {% if link %}<p><a href="{{ link }}">{{ link }}</a></p>{% endif %} - {% endfor %} - </ul> - </div> - </div> - {% endif %} </main> - </body> </html> diff --git a/renderer/templates/test_case.html b/renderer/templates/test_case.html new file mode 100644 index 0000000..6cf942f --- /dev/null +++ b/renderer/templates/test_case.html @@ -0,0 +1,108 @@ +<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> + <link href="css/bootstrap.min.css" rel="stylesheet"> + <title>{{ name }}</title> + </head> + <body> + {% import 'templates/macros.html' as macros %} + <main role="main" class="container" style="margin-top: 40px; margin-bottom: 40px"> + <h2>{{ name }} <small class="text-muted">{{ exec_type }}</small></h2> + <h3><span class="badge badge-{{ priority_color }}">{{ priority }}</span></h3> + + <div class="card" style="margin-top: 20px"> + <div class="card-body"> + <dl class="row"> + <dt class="col-sm-3">Image Type:</dt> + <dd class="col-sm-9">{{ image_type }}</dd> + <dt class="col-sm-3">Image Architecture:</dt> + <dd class="col-sm-9">{{ image_arch }}</dd> + <dt class="col-sm-3">Type:</dt> + <dd class="col-sm-9">{{ type }}</dd> + </dl> + + <h4>Description</h4> + <p>{{ description }}</p> + + {% if resources %} + <hr /> + <h4>Resources</h4> + <ul> + {% for resource in resources %} + <li>{{ resource|e }}</li> + {% endfor %} + </ul> + {% endif %} + + {% if pre_conditions or pkgname or packages_list or libname %} + <hr /> + <h4>Pre Conditions</h4> + <ol> + {% if pkgname %}{{ macros.ostree_preconditions(pkgname) }}{% endif %} + {% if packages_list %}{{ macros.install_packages(packages_list) }}{% endif %} + {% if libname %}{{ macros.modules_preconditions(libname) }}{% endif %} + {% for comment, command, output, _, link in pre_conditions %} + {% if comment %}<li class="mb-sm-2">{{ comment|e }}</li>{% endif %} + {% if command %}<p><kbd>{{ command|e }}</kbd></p>{% endif %} + {% if link %}<p><a href="{{ link }}">{{ link }}</a></p>{% endif %} + {% if output %}{% for l in output %}<p class="mb-sm-0 pl-sm-3"><samp>{{ l|e }}</samp></p>{% endfor %}{% endif %} + {% endfor %} + </ol> + {% endif %} + + <hr /> + <h4>Execution Steps</h4> + <ol> + {% for comment, command, output, _, link in run_steps %} + {% if comment %}<li class="mb-sm-2">{{ comment|e }}</li>{% endif %} + {% if command %}<p><kbd>{{ command|e }}</kbd></p>{% endif %} + {% if output %}{% for l in output %}<p class="mb-sm-0 pl-sm-3"><samp>{{ l|e }}</samp></p>{% endfor %}{% endif %} + {% endfor %} + </ol> + + <hr /> + <h4>Expected</h4> + {% for comment, command, output, image, link in expected %} + {% if comment %}<p class="mt-sm-3">{{ comment|e }}</p>{% endif %} + {% if command %}<p><kbd>{{ command|e }}</kbd></p>{% endif %} + {% if output %}{% for l in output %}<p class="mb-sm-0 pl-sm-3"><samp>{{ l|e }}</samp></p>{% endfor %}{% endif %} + {% if image %}<img src="images/{{ image }}" class="img-fluid">{% endif %} + {% if link %}<p><a href="{{ link }}">{{ link }}</a></p>{% endif %} + {% endfor %} + + {% if post_conditions %} + <hr /> + <h4>Post Conditions</h4> + <ol> + {% for comment, command, output, _, link in post_conditions %} + {% if comment %}<li class="mb-sm-2">{{ comment|e }}</li>{% endif %} + {% if command %}<p><kbd>{{ command|e }}</kbd></p>{% endif %} + {% if output %}{% for l in output %}<p class="mb-sm-0 pl-sm-3"><samp>{{ l|e }}</samp></p>{% endfor %}{% endif %} + {% endfor %} + </ol> + {% endif %} + + </div> + </div> + + {% if notes %} + <div class="card" style="margin-top: 30px"> + <div class="card-body"> + <h4>Notes</h4> + <ul> + {% for comment, command, output, _, link in notes %} + {% if comment %}<li class="mb-sm-2">{{ comment|e }}</li>{% endif %} + {% if command %}<p><kbd>{{ command|e }}</kbd></p>{% endif %} + {% if output %}{% for l in output %}<p class="mb-sm-0 pl-sm-3"><samp>{{ l|e }}</samp></p>{% endfor %}{% endif %} + {% if link %}<p><a href="{{ link }}">{{ link }}</a></p>{% endif %} + {% endfor %} + </ul> + </div> + </div> + {% endif %} + </main> + + </body> +</html> diff --git a/renderer/tests.py b/renderer/tests.py index 43d40e1..dbe6bf0 100644 --- a/renderer/tests.py +++ b/renderer/tests.py @@ -26,7 +26,7 @@ import os.path import copy from parser import parse_format -from renderer import parse_list, generate_test_case +from renderer import parse_list, generate_test_case_page from exceptions import ParserTypeError, ParserMissingFieldError @@ -229,21 +229,21 @@ class TestRenderFile(unittest.TestCase): """ def test_render_file1(self): - tc_file = os.path.join(TESTS_FILES_PATH, "test_file1.yaml") - tc_page = read_file(os.path.join(TESTS_FILES_PATH, "test_file1.html")) - self.assertEqual(generate_test_case(tc_file, return_out=True), tc_page) + tcfile = os.path.join(TESTS_FILES_PATH, "test_file1.yaml") + page = read_file(os.path.join(TESTS_FILES_PATH, "test_file1.html")) + self.assertEqual(generate_test_case_page(tcfile, return_out=True), page) def test_render_file3(self): - tc_file = os.path.join(TESTS_FILES_PATH, "test_file3.yaml") - tc_page = read_file(os.path.join(TESTS_FILES_PATH, "test_file3.html")) - self.assertEqual(generate_test_case(tc_file, return_out=True), tc_page) + tcfile = os.path.join(TESTS_FILES_PATH, "test_file3.yaml") + page = read_file(os.path.join(TESTS_FILES_PATH, "test_file3.html")) + self.assertEqual(generate_test_case_page(tcfile, return_out=True), page) def test_render_file4(self): - tc_file = os.path.join(TESTS_FILES_PATH, "test_file4.yaml") - tc_page = read_file(os.path.join(TESTS_FILES_PATH, "test_file4.html")) - self.assertEqual(generate_test_case(tc_file, return_out=True), tc_page) + tcfile = os.path.join(TESTS_FILES_PATH, "test_file4.yaml") + page = read_file(os.path.join(TESTS_FILES_PATH, "test_file4.html")) + self.assertEqual(generate_test_case_page(tcfile, return_out=True), page) def test_render_file5(self): - tc_file = os.path.join(TESTS_FILES_PATH, "test_file5.yaml") - tc_page = read_file(os.path.join(TESTS_FILES_PATH, "test_file5.html")) - self.assertEqual(generate_test_case(tc_file, return_out=True), tc_page) + tcfile = os.path.join(TESTS_FILES_PATH, "test_file5.yaml") + page = read_file(os.path.join(TESTS_FILES_PATH, "test_file5.html")) + self.assertEqual(generate_test_case_page(tcfile, return_out=True), page) -- GitLab