diff --git a/cmd/install b/cmd/install
index 4e8639a66..6477b85fb 100755
--- a/cmd/install
+++ b/cmd/install
@@ -20,4 +20,8 @@ source venv/bin/activate
pip3 install -r framework/requirements.txt
-deactivate
+# Dependency for printing reports to pdf
+# required by python package weasyprint
+sudo apt-get install libpangocairo-1.0-0
+
+deactivate
\ No newline at end of file
diff --git a/framework/python/src/common/testreport.py b/framework/python/src/common/testreport.py
index ba35ff27a..d57db58cf 100644
--- a/framework/python/src/common/testreport.py
+++ b/framework/python/src/common/testreport.py
@@ -15,6 +15,8 @@
"""Store previous test run information."""
from datetime import datetime
+from weasyprint import HTML
+from io import BytesIO
DATE_TIME_FORMAT = '%Y-%m-%d %H:%M:%S'
@@ -82,3 +84,91 @@ def from_json(self, json_file):
self.add_test(test_result)
return self
+
+ # Create a pdf file in memory and return the bytes
+ def to_pdf(self):
+ # Resolve the data as html first
+ report_html = self.to_html()
+
+ # Convert HTML to PDF in memory using weasyprint
+ pdf_bytes = BytesIO()
+ HTML(string=report_html).write_pdf(pdf_bytes)
+ return pdf_bytes
+
+ def to_html(self):
+ json_data = self.to_json()
+ return f'''
+
+
+ {self.generate_header()}
+
+ Test Results Summary
+
+
+
Device Information
+
MAC Address: {json_data["device"]["mac_addr"]}
+
Manufacturer: {json_data["device"]["manufacturer"] or "Unknown"}
+
Model: {json_data["device"]["model"]}
+
+
+ Test Results
+ {self.generate_test_sections(json_data)}
+
+
+ '''
+
+ def generate_test_sections(self,json_data):
+ results = json_data["tests"]["results"]
+ sections = ""
+ for result in results:
+ sections += self.generate_test_section(result)
+ return sections
+
+ def generate_test_section(self, result):
+ section_content = '\n'
+ for key, value in result.items():
+ if value is not None: # Check if the value is not None
+ formatted_key = key.replace('_', ' ').title() # Replace underscores and capitalize
+ section_content += f'{formatted_key}: {value}
\n'
+ section_content += '\n\n'
+ return section_content
+
+ def generate_header(self):
+ return f'''
+
+
+
+ Test Results Summary
+
+
+ '''
+
+ def generate_css(self):
+ return '''
+ body {
+ font-family: Arial, sans-serif;
+ margin: 20px;
+ }
+ h1 {
+ margin-bottom: 10px;
+ }
+ .summary {
+ border: 1px solid #ccc;
+ padding: 10px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ }
+ .test-list {
+ list-style: none;
+ padding: 0;
+ }
+ .test-item {
+ margin-bottom: 10px;
+ }
+ .test-link {
+ text-decoration: none;
+ color: #007bff;
+ }
+ '''
\ No newline at end of file
diff --git a/framework/python/src/test_orc/test_orchestrator.py b/framework/python/src/test_orc/test_orchestrator.py
index eb5676e17..5835a4fed 100644
--- a/framework/python/src/test_orc/test_orchestrator.py
+++ b/framework/python/src/test_orc/test_orchestrator.py
@@ -86,6 +86,8 @@ def run_test_modules(self):
report = TestReport().from_json(self._generate_report())
device.add_report(report)
+ self._write_reports(report)
+
self._test_in_progress = False
self._timestamp_results(device)
@@ -95,6 +97,25 @@ def run_test_modules(self):
LOGGER.debug("Old test results cleaned")
self._test_in_progress = False
+ def _write_reports(self, test_report):
+ out_dir = os.path.join(
+ self._root_path, RUNTIME_DIR,
+ self._session.get_target_device().mac_addr.replace(":", ""))
+
+ # Write the json report
+ with open(os.path.join(out_dir,"report.json"),"w", encoding="utf-8") as f:
+ json.dump(test_report.to_json(), f, indent=2)
+
+ # Write the html report
+ with open(os.path.join(out_dir,"report.html"),"w", encoding="utf-8") as f:
+ f.write(test_report.to_html())
+
+ # Write the pdf report
+ with open(os.path.join(out_dir,"report.pdf"),"wb") as f:
+ f.write(test_report.to_pdf().getvalue())
+
+ util.run_command(f"chown -R {self._host_user} {out_dir}")
+
def _generate_report(self):
report = {}
@@ -105,14 +126,6 @@ def _generate_report(self):
"%Y-%m-%d %H:%M:%S")
report["status"] = self._calculate_result()
report["tests"] = self._session.get_report_tests()
- out_file = os.path.join(
- self._root_path, RUNTIME_DIR,
- self._session.get_target_device().mac_addr.replace(":", ""),
- "report.json")
-
- with open(out_file, "w", encoding="utf-8") as f:
- json.dump(report, f, indent=2)
- util.run_command(f"chown -R {self._host_user} {out_file}")
return report
def _calculate_result(self):
diff --git a/framework/requirements.txt b/framework/requirements.txt
index 560c2baf9..7141ae706 100644
--- a/framework/requirements.txt
+++ b/framework/requirements.txt
@@ -7,6 +7,9 @@ ipaddress
netifaces
scapy
+# Requirments for the test_orc module
+weasyprint
+
# Requirements for the API
fastapi==0.99.1
psutil