From 14f69172c0a4b2ba5cef4519d5c212cf6be6ecd7 Mon Sep 17 00:00:00 2001 From: MariusBaldovin Date: Tue, 11 Feb 2025 15:07:06 +0000 Subject: [PATCH 1/7] fixed reports unittest --- framework/python/src/common/testreport.py | 2 - .../pilot/report_templates/summary.jinja | 8 +- .../report_templates/summary.jinja | 2 +- ...=> pilot_do_not_proceed_noncompliant.json} | 1 + ...ilot.json => pilot_proceed_compliant.json} | 0 .../report/pilot_proceed_noncompliant.json | 346 ++++++++++++++++++ ...iant.json => qualification_compliant.json} | 5 +- ...t.json => qualification_noncompliant.json} | 3 +- testing/unit/report/report_test.py | 61 +-- 9 files changed, 396 insertions(+), 32 deletions(-) rename testing/unit/report/{report_noncompliant_pilot.json => pilot_do_not_proceed_noncompliant.json} (99%) rename testing/unit/report/{report_compliant_pilot.json => pilot_proceed_compliant.json} (100%) create mode 100644 testing/unit/report/pilot_proceed_noncompliant.json rename testing/unit/report/{report_compliant.json => qualification_compliant.json} (97%) rename testing/unit/report/{report_noncompliant.json => qualification_noncompliant.json} (97%) diff --git a/framework/python/src/common/testreport.py b/framework/python/src/common/testreport.py index fbd993a8e..70603ef6c 100644 --- a/framework/python/src/common/testreport.py +++ b/framework/python/src/common/testreport.py @@ -50,8 +50,6 @@ report_resource_dir = os.path.join(root_dir, RESOURCES_DIR) test_run_img_file = os.path.join(report_resource_dir, 'testrun.png') -qualification_icon = os.path.join(report_resource_dir, 'qualification-icon.png') -pilot_icon = os.path.join(report_resource_dir, 'pilot-icon.png') class TestReport(): diff --git a/resources/test_packs/pilot/report_templates/summary.jinja b/resources/test_packs/pilot/report_templates/summary.jinja index cd46fdd3e..bedf6d383 100644 --- a/resources/test_packs/pilot/report_templates/summary.jinja +++ b/resources/test_packs/pilot/report_templates/summary.jinja @@ -30,17 +30,17 @@ {% endfor %} - {% if test_status in ['Compliant', 'Proceed'] %} + {% if json_data['status'] == 'Proceed' %}
{% else %}
{% endif %}
Test Status
Complete
-
Pilot Recommendation
-
{{ json_data['status'] }}
Test Result
-
{{ json_data['result'] }}
+
{{ json_data['result'] }}
+
Pilot Recommendation
+
{{ json_data['status'] }}
Started
{{ json_data['started']}}
Duration
diff --git a/resources/test_packs/qualification/report_templates/summary.jinja b/resources/test_packs/qualification/report_templates/summary.jinja index eb3e367dc..23d5ade1b 100644 --- a/resources/test_packs/qualification/report_templates/summary.jinja +++ b/resources/test_packs/qualification/report_templates/summary.jinja @@ -30,7 +30,7 @@
{% endfor %}
- {% if test_status == 'Compliant' %} + {% if json_data['result'] == 'Compliant' %}
{% else %}
diff --git a/testing/unit/report/report_noncompliant_pilot.json b/testing/unit/report/pilot_do_not_proceed_noncompliant.json similarity index 99% rename from testing/unit/report/report_noncompliant_pilot.json rename to testing/unit/report/pilot_do_not_proceed_noncompliant.json index 7d36c9dcc..b210a365b 100644 --- a/testing/unit/report/report_noncompliant_pilot.json +++ b/testing/unit/report/pilot_do_not_proceed_noncompliant.json @@ -55,6 +55,7 @@ ] }, "status": "Do Not Proceed", + "result": "Non-Compliant", "started": "2024-04-10 21:21:47", "finished": "2024-04-10 21:35:43", "tests": { diff --git a/testing/unit/report/report_compliant_pilot.json b/testing/unit/report/pilot_proceed_compliant.json similarity index 100% rename from testing/unit/report/report_compliant_pilot.json rename to testing/unit/report/pilot_proceed_compliant.json diff --git a/testing/unit/report/pilot_proceed_noncompliant.json b/testing/unit/report/pilot_proceed_noncompliant.json new file mode 100644 index 000000000..f97d915cf --- /dev/null +++ b/testing/unit/report/pilot_proceed_noncompliant.json @@ -0,0 +1,346 @@ +{ + "device": { + "mac_addr": "aa:bb:cc:dd:ee:ff", + "manufacturer": "Testrun", + "model": "Faux", + "firmware": "1.0.0", + "type": "Controller - FCU", + "technology": "Hardware - Fitness", + "test_pack": "Pilot Assessment", + "test_modules": { + "connection": { + "enabled": true + }, + "ntp": { + "enabled": true + }, + "dns": { + "enabled": true + }, + "services": { + "enabled": true + }, + "tls": { + "enabled": true + }, + "protocol": { + "enabled": true + } + }, + "additional_info": [ + { + "question": "What type of device is this?", + "answer": "Controller - FCU" + }, + { + "question": "Please select the technology this device falls into", + "answer": "Hardware - Fitness" + }, + { + "question": "Does your device process any sensitive information? ", + "answer": "No" + }, + { + "question": "Can all non-essential services be disabled on your device?", + "answer": "Yes" + }, + { + "question": "Is there a second IP port on the device?", + "answer": "No" + }, + { + "question": "Can the second IP port on your device be disabled?", + "answer": "N/A" + } + ] + }, + "status": "Proceed", + "result": "Non-Compliant", + "started": "2024-04-10 21:21:47", + "finished": "2024-04-10 21:35:43", + "tests": { + "total": 33, + "results": [ + { + "name": "protocol.valid_bacnet", + "description": "Device IP matches discovered device", + "expected_behavior": "BACnet traffic can be seen on the network and packets are valid and not malformed", + "required_result": "Recommended", + "result": "Compliant" + }, + { + "name": "protocol.bacnet.version", + "description": "BACnet protocol version detected: 1.15", + "expected_behavior": "The BACnet client implements an up to date version of BACnet", + "required_result": "Recommended", + "result": "Compliant" + }, + { + "name": "protocol.valid_modbus", + "description": "Established connection to modbus port: 502\nHolding registers succesfully read: 0:5\nInput registers succesfully read: 0:5\nCoil registers succesfully read: 0:1\nDiscrete inputs succesfully read: 0:1", + "expected_behavior": "Any Modbus functionality works as expected and valid Modbus traffic can be observed", + "required_result": "Recommended", + "result": "Compliant" + }, + { + "name": "security.tls.v1_2_server", + "description": "TLS 1.2 certificate could not be validated", + "expected_behavior": "TLS 1.2 certificate is issued to the web browser client when accessed", + "required_result": "Required", + "result": "Non-Compliant", + "recommendations": [ + "Enable TLS 1.2 support in the web server configuration", + "Disable TLS 1.0 and 1.1", + "Sign the certificate used by the web server" + ] + }, + { + "name": "security.tls.v1_2_client", + "description": "TLS 1.2 client connections invalid", + "expected_behavior": "The packet indicates a TLS connection with at least TLS 1.2 and support for ECDH and ECDSA ciphers", + "required_result": "Required", + "result": "Non-Compliant", + "recommendations": [ + "Disable connections to unsecure services", + "Ensure any URLs connected to are secure (https)" + ] + }, + { + "name": "connection.switch.arp_inspection", + "description": "Device uses ARP correctly", + "expected_behavior": "Device continues to operate correctly when ARP inspection is enabled on the switch. No functionality is lost with ARP inspection enabled.", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "connection.switch.dhcp_snooping", + "description": "Device does not act as a DHCP server", + "expected_behavior": "Device continues to operate correctly when DHCP snooping is enabled on the switch.", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "connection.dhcp_address", + "description": "No DHCP lease could be found", + "expected_behavior": "The device is not setup with a static IP address. The device accepts an IP address from a DHCP server (RFC 2131) and responds succesfully to an ICMP echo (ping) request.", + "required_result": "Required", + "result": "Non-Compliant", + "recommendations": [ + "Enable DHCP", + "Install a DHCP client" + ] + }, + { + "name": "connection.mac_address", + "description": "No MAC address found", + "expected_behavior": "N/A", + "required_result": "Required", + "result": "Non-Compliant", + "recommendations": [ + "Ensure that the MAC address is set by hardware only" + ] + }, + { + "name": "connection.mac_oui", + "description": "OUI Manufacturer found: Texas Instruments", + "expected_behavior": "The MAC address prefix is registered in the IEEE Organizationally Unique Identifier database.", + "required_result": "Required", + "result": "Compliant", + "recommendations": [ + "No OUI Manufacturer found for aa:bb:cc:dd:ee:ff" + ] + }, + { + "name": "connection.private_address", + "description": "Subnet 10.0.0.100-10.0.0.200 failed", + "expected_behavior": "The device under test accepts IP addresses within all ranges specified in RFC 1918 and communicates using these addresses. The Internet Assigned Numbers Authority (IANA) has reserved the following three blocks of the IP address space for private internets. 10.0.0.0 - 10.255.255.255.255 (10/8 prefix). 172.16.0.0 - 172.31.255.255 (172.16/12 prefix). 192.168.0.0 - 192.168.255.255 (192.168/16 prefix)", + "required_result": "Required", + "result": "Non-Compliant", + "recommendations": [ + "Install a DHCP client that supports private address space" + ] + }, + { + "name": "connection.shared_address", + "description": "Subnet 100.64.0.1-100.64.255.254 failed", + "expected_behavior": "The device under test accepts IP addresses within the ranges specified in RFC 6598 and communicates using these addresses", + "required_result": "Required", + "result": "Non-Compliant", + "recommendations": [ + "Install a DHCP client that supports shared address space", + "Enable shared address space support in the DHCP client" + ] + }, + { + "name": "connection.single_ip", + "description": "Device is using multiple IP addresses", + "expected_behavior": "The device under test does not behave as a network switch and only requets one IP address. This test is to avoid that devices implement network switches that allow connecting strings of daisy chained devices to one single network port, as this would not make 802.1x port based authentication possible.", + "required_result": "Required", + "result": "Non-Compliant", + "recommendations": [ + "Ensure that all ports on the device are isolated", + "Ensure only one DHCP client is running" + ] + }, + { + "name": "connection.target_ping", + "description": "Device does not respond to ping", + "expected_behavior": "The device under test responds to an ICMP echo (ping) request.", + "required_result": "Required", + "result": "Non-Compliant", + "recommendations": [ + "Configure device to allow ICMP requests (ping)", + "Create a firewall exception to allow ICMP requests from LAN" + ] + }, + { + "name": "connection.ipaddr.ip_change", + "description": "Device did not accept IP address change", + "expected_behavior": "If the lease expires before the client receiveds a DHCPACK, the client moves to INIT state, MUST immediately stop any other network processing and requires network initialization parameters as if the client were uninitialized. If the client then receives a DHCPACK allocating the client its previous network addres, the client SHOULD continue network processing. If the client is given a new network address, it MUST NOT continue using the previous network address and SHOULD notify the local users of the problem.", + "required_result": "Required", + "result": "Non-Compliant", + "recommendations": [ + "Install a compliant DHCP client" + ] + }, + { + "name": "connection.ipaddr.dhcp_failover", + "description": "Device did not recieve a new lease from secondary DHCP server'", + "expected_behavior": "", + "required_result": "Required", + "result": "Non-Compliant", + "recommendations": [ + "Install a compliant DHCP client" + ] + }, + { + "name": "connection.ipv6_slaac", + "description": "Device does not support IPv6 SLAAC", + "expected_behavior": "The device under test complies with RFC4862 and forms a valid IPv6 SLAAC address", + "required_result": "Required", + "result": "Non-Compliant", + "recommendations": [ + "Install a network manager that supports IPv6", + "Disable DHCPv6" + ] + }, + { + "name": "connection.ipv6_ping", + "description": "No IPv6 SLAAC address found. Cannot ping", + "expected_behavior": "The device responds to the ping as per RFC4443", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "dns.network.hostname_resolution", + "description": "DNS traffic detected from device", + "expected_behavior": "The device sends DNS requests.", + "required_result": "Required", + "result": "Non-Compliant", + "recommendations": [ + "Enable ping response to IPv6 ICMP requests in network manager settings", + "Create a firewall exception to allow ICMPv6 via LAN" + ] + }, + { + "name": "dns.network.from_dhcp", + "description": "DNS traffic detected only to DHCP provided server", + "expected_behavior": "The device sends DNS requests to the DNS server provided by the DHCP server", + "required_result": "Roadmap", + "result": "Compliant" + }, + { + "name": "security.services.ftp", + "description": "No FTP server found", + "expected_behavior": "There is no FTP service running on any port", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "security.ssh.version", + "description": "No SSH server found", + "expected_behavior": "SSH server is not running or server is SSHv2", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "security.services.telnet", + "description": "No telnet server found", + "expected_behavior": "There is no Telnet service running on any port", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "security.services.smtp", + "description": "No SMTP server found", + "expected_behavior": "There is no SMTP service running on any port", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "security.services.http", + "description": "No HTTP server found", + "expected_behavior": "Device is unreachable on port 80 (or any other port) and only responds to HTTPS requests on port 443 (or any other port if HTTP is used at all)", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "security.services.pop", + "description": "No POP server found", + "expected_behavior": "There is no POP service running on any port", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "security.services.imap", + "description": "No IMAP server found", + "expected_behavior": "There is no IMAP service running on any port", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "security.services.snmpv3", + "description": "No SNMP server found", + "expected_behavior": "Device is unreachable on port 161 (or any other port) and device is unreachable on port 162 (or any other port) unless SNMP is essential in which case it is SNMPv3 is used.", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "security.services.vnc", + "description": "No VNC server found", + "expected_behavior": "Device cannot be accessed / connected to via VNC on any port", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "security.services.tftp", + "description": "No TFTP server found", + "expected_behavior": "There is no TFTP service running on any port", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "ntp.network.ntp_server", + "description": "No NTP server found", + "expected_behavior": "The device does not respond to NTP requests when it's IP is set as the NTP server on another device", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "ntp.network.ntp_support", + "description": "Device sent NTPv4 packets.", + "expected_behavior": "The device sends an NTPv4 request to the configured NTP server.", + "required_result": "Required", + "result": "Compliant" + }, + { + "name": "ntp.network.ntp_dhcp", + "description": "Device sent NTP request to non-DHCP provided server", + "expected_behavior": "Device can accept NTP server address, provided by the DHCP server (DHCP OFFER PACKET)", + "required_result": "Roadmap", + "result": "Non-Compliant" + } + ] + }, + "report": "http://localhost:8000/report/Testrun Faux/2024-04-10T21:21:47" + } \ No newline at end of file diff --git a/testing/unit/report/report_compliant.json b/testing/unit/report/qualification_compliant.json similarity index 97% rename from testing/unit/report/report_compliant.json rename to testing/unit/report/qualification_compliant.json index 6b84a8d39..dbbb92021 100644 --- a/testing/unit/report/report_compliant.json +++ b/testing/unit/report/qualification_compliant.json @@ -54,7 +54,8 @@ } ] }, - "status": "Compliant", + "status": "Complete", + "result": "Compliant", "started": "2024-04-10 21:21:47", "finished": "2024-04-10 21:35:43", "tests": { @@ -289,7 +290,7 @@ "description": "Device sent NTP request to non-DHCP provided server", "expected_behavior": "Device can accept NTP server address, provided by the DHCP server (DHCP OFFER PACKET)", "required_result": "Roadmap", - "result": "Non-Compliant" + "result": "Compliant" } ] }, diff --git a/testing/unit/report/report_noncompliant.json b/testing/unit/report/qualification_noncompliant.json similarity index 97% rename from testing/unit/report/report_noncompliant.json rename to testing/unit/report/qualification_noncompliant.json index 6619bba19..e75086abc 100644 --- a/testing/unit/report/report_noncompliant.json +++ b/testing/unit/report/qualification_noncompliant.json @@ -54,7 +54,8 @@ } ] }, - "status": "Non-Compliant", + "status": "Complete", + "result": "Non-Compliant", "started": "2024-04-10 21:21:47", "finished": "2024-04-10 21:35:43", "tests": { diff --git a/testing/unit/report/report_test.py b/testing/unit/report/report_test.py index 48a815114..ad7a29dde 100644 --- a/testing/unit/report/report_test.py +++ b/testing/unit/report/report_test.py @@ -30,7 +30,7 @@ REPORT_RESOURCES_DIR = 'resources/report' CSS_PATH = os.path.join(REPORT_RESOURCES_DIR, 'test_report_styles.css') -HTML_PATH = os.path.join(REPORT_RESOURCES_DIR, 'test_report_template.html') +HTML_PATH = 'resources/test_packs/pilot/report_templates/report_template.html' class ReportTest(unittest.TestCase): """Contains and runs all the unit tests concerning DNS behaviors""" @@ -81,35 +81,43 @@ def create_report(self, results_file_path): with open(report_pdf_file, 'wb') as file: file.write(report.to_pdf().getvalue()) - def report_compliant_test(self): - """Generate a report for the compliant test""" + def qualification_compliant_test(self): + """Generate a report for the qualification compliant test""" # Generate a compliant report based on the 'report_compliant.json' file - self.create_report(os.path.join(TEST_FILES_DIR, 'report_compliant.json')) + self.create_report(os.path.join(TEST_FILES_DIR, + 'qualification_compliant.json')) + + def qualification_noncompliant_test(self): + """Generate a report for the qualification non-compliant test""" + + # Generate non-compliant report based on the 'report_noncompliant.json' file + self.create_report(os.path.join(TEST_FILES_DIR, + 'qualification_noncompliant.json')) - def report_compliant_pilot_test(self): + def pilot_proceed_compliant_test(self): """Generate a report for the compliant test with a pilot device""" # Generate a compliant report based on the # 'report_compliant_pilot.json' file self.create_report(os.path.join(TEST_FILES_DIR, - 'report_compliant_pilot.json')) - - def report_noncompliant_test(self): - """Generate a report for the non-compliant test""" + 'pilot_proceed_compliant.json')) - # Generate non-compliant report based on the 'report_noncompliant.json' file - self.create_report(os.path.join(TEST_FILES_DIR, 'report_noncompliant.json')) + def pilot_proceed_noncompliant_test(self): + """Generate a report for the non-compliant test with a pilot device""" + # Generate a compliant report based on the + # 'report_noncompliant_pilot.json' file + self.create_report(os.path.join(TEST_FILES_DIR, + 'pilot_proceed_noncompliant.json')) - def report_noncompliant_pilot_test(self): + def pilot_do_not_proceed_noncompliant_test(self): """Generate a report for the non-compliant test with a pilot device""" # Generate a compliant report based on the # 'report_noncompliant_pilot.json' file self.create_report(os.path.join(TEST_FILES_DIR, - 'report_noncompliant_pilot.json')) - + 'pilot_do_not_proceed_noncompliant.json')) # Generate formatted reports for each report generated from # the test containers. # Not a unit test but can't run from within the test module container and must @@ -135,6 +143,7 @@ def report_formatting(self): # Check if output dir exists if os.path.isdir(output_dir): + # List all files fro output dir output_files = os.listdir(output_dir) @@ -144,12 +153,14 @@ def report_formatting(self): # Chck if is an html file if file.endswith('.html'): - # Construct teh full path of html file + # Construct the full path of html file report_out_path = os.path.join(output_dir,file) # Open the html file in read mode with open(report_out_path, 'r', encoding='utf-8') as f: report_out = f.read() + print(f'HTML file before formatting: {report_out}') + # Add the formatting formatted_report = self.add_html_formatting(report_out) @@ -169,7 +180,13 @@ def add_html_formatting(self, body): with open(CSS_PATH, 'r', encoding='UTF-8') as css_file: styles = css_file.read() - # Load the html file + # Add the device details + device = {'device': { + 'manufacturer': 'Testrun', + 'model': 'Faux' + }} + + # Load the report_template.html file with open(HTML_PATH, 'r', encoding='UTF-8') as html_file: html_content = html_file.read() @@ -188,8 +205,7 @@ def add_html_formatting(self, body): # Create a Jinja2 template from the string template = Template(html_template) - # Render the template with css styles - return template.render(styles=styles, body=body) + return template.render(styles=styles, body=body, device=device) def get_module_html_report(self, module): """Load the HTML report for a specific module""" @@ -209,10 +225,11 @@ def get_module_html_report(self, module): if __name__ == '__main__': suite = unittest.TestSuite() - suite.addTest(ReportTest('report_compliant_test')) - suite.addTest(ReportTest('report_noncompliant_test')) - suite.addTest(ReportTest('report_compliant_pilot_test')) - suite.addTest(ReportTest('report_noncompliant_pilot_test')) + suite.addTest(ReportTest('qualification_compliant_test')) + suite.addTest(ReportTest('qualification_noncompliant_test')) + suite.addTest(ReportTest('pilot_proceed_compliant_test')) + suite.addTest(ReportTest('pilot_do_not_proceed_noncompliant_test')) + suite.addTest(ReportTest('pilot_do_not_proceed_noncompliant_test')) # Create html test reports for each module in 'output' dir suite.addTest(ReportTest('report_formatting')) From f4357a0d293ecc566103222175789e1a5c99d2e1 Mon Sep 17 00:00:00 2001 From: MariusBaldovin Date: Tue, 11 Feb 2025 15:13:45 +0000 Subject: [PATCH 2/7] added pilot_proceed_noncompliant_test --- testing/unit/report/report_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/unit/report/report_test.py b/testing/unit/report/report_test.py index ad7a29dde..e6ede67dd 100644 --- a/testing/unit/report/report_test.py +++ b/testing/unit/report/report_test.py @@ -228,7 +228,7 @@ def get_module_html_report(self, module): suite.addTest(ReportTest('qualification_compliant_test')) suite.addTest(ReportTest('qualification_noncompliant_test')) suite.addTest(ReportTest('pilot_proceed_compliant_test')) - suite.addTest(ReportTest('pilot_do_not_proceed_noncompliant_test')) + suite.addTest(ReportTest('pilot_proceed_noncompliant_test')) suite.addTest(ReportTest('pilot_do_not_proceed_noncompliant_test')) # Create html test reports for each module in 'output' dir From d3a7e3c1a8ac5071bf2d15f059404bcb0de23150 Mon Sep 17 00:00:00 2001 From: MariusBaldovin Date: Tue, 11 Feb 2025 15:43:42 +0000 Subject: [PATCH 3/7] change to Preliminary Pilot Recommendation --- resources/test_packs/pilot/report_templates/summary.jinja | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/test_packs/pilot/report_templates/summary.jinja b/resources/test_packs/pilot/report_templates/summary.jinja index bedf6d383..7e5186a7f 100644 --- a/resources/test_packs/pilot/report_templates/summary.jinja +++ b/resources/test_packs/pilot/report_templates/summary.jinja @@ -39,7 +39,7 @@
Complete
Test Result
{{ json_data['result'] }}
-
Pilot Recommendation
+
Preliminary Pilot Recommendation
{{ json_data['status'] }}
Started
{{ json_data['started']}}
From 821352a22c3c678ad4541876f2b0f6accbf3d8b5 Mon Sep 17 00:00:00 2001 From: MariusBaldovin Date: Tue, 11 Feb 2025 15:54:35 +0000 Subject: [PATCH 4/7] remove the print report statement --- modules/ui/package-lock.json | 262 ++++++++--------------------- testing/unit/report/report_test.py | 1 - 2 files changed, 71 insertions(+), 192 deletions(-) diff --git a/modules/ui/package-lock.json b/modules/ui/package-lock.json index 6d6356513..1993d3a21 100644 --- a/modules/ui/package-lock.json +++ b/modules/ui/package-lock.json @@ -569,6 +569,34 @@ "typescript": ">=5.4 <5.6" } }, + "node_modules/@angular/compiler-cli/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@angular/compiler-cli/node_modules/readdirp": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", + "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", + "dev": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@angular/core": { "version": "18.2.13", "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.13.tgz", @@ -5881,18 +5909,39 @@ "dev": true }, "node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, "dependencies": { - "readdirp": "^4.0.1" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": ">= 14.16.0" + "node": ">= 8.10.0" }, "funding": { "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, "node_modules/chownr": { @@ -9286,30 +9335,6 @@ "concat-map": "0.0.1" } }, - "node_modules/karma/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/karma/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -9327,18 +9352,6 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/karma/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/karma/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -9360,30 +9373,6 @@ "node": "*" } }, - "node_modules/karma/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/karma/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/karma/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -12417,16 +12406,27 @@ } }, "node_modules/readdirp": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", - "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, "engines": { - "node": ">= 14.18.0" + "node": ">=8.10.0" + } + }, + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" }, "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/reflect-metadata": { @@ -12866,66 +12866,6 @@ } } }, - "node_modules/sass/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/sass/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/sass/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/sass/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/sax": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", @@ -15266,30 +15206,6 @@ } } }, - "node_modules/webpack-dev-server/node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, "node_modules/webpack-dev-server/node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -15310,18 +15226,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/webpack-dev-server/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", @@ -15346,30 +15250,6 @@ } } }, - "node_modules/webpack-dev-server/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/webpack-dev-server/node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/webpack-dev-server/node_modules/rimraf": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", diff --git a/testing/unit/report/report_test.py b/testing/unit/report/report_test.py index e6ede67dd..a24f1e7eb 100644 --- a/testing/unit/report/report_test.py +++ b/testing/unit/report/report_test.py @@ -159,7 +159,6 @@ def report_formatting(self): # Open the html file in read mode with open(report_out_path, 'r', encoding='utf-8') as f: report_out = f.read() - print(f'HTML file before formatting: {report_out}') # Add the formatting formatted_report = self.add_html_formatting(report_out) From 66e6202268d28f3a12074045b016e243591adcd8 Mon Sep 17 00:00:00 2001 From: MariusBaldovin Date: Tue, 11 Feb 2025 16:45:59 +0000 Subject: [PATCH 5/7] updated comments --- testing/unit/report/report_test.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/testing/unit/report/report_test.py b/testing/unit/report/report_test.py index a24f1e7eb..d1093ff28 100644 --- a/testing/unit/report/report_test.py +++ b/testing/unit/report/report_test.py @@ -84,40 +84,38 @@ def create_report(self, results_file_path): def qualification_compliant_test(self): """Generate a report for the qualification compliant test""" - # Generate a compliant report based on the 'report_compliant.json' file + # Generate the report self.create_report(os.path.join(TEST_FILES_DIR, 'qualification_compliant.json')) def qualification_noncompliant_test(self): """Generate a report for the qualification non-compliant test""" - # Generate non-compliant report based on the 'report_noncompliant.json' file + # Generate the report self.create_report(os.path.join(TEST_FILES_DIR, 'qualification_noncompliant.json')) def pilot_proceed_compliant_test(self): - """Generate a report for the compliant test with a pilot device""" + """Generate a report for proceed/compliant test with a pilot device""" - # Generate a compliant report based on the - # 'report_compliant_pilot.json' file + # Generate the report self.create_report(os.path.join(TEST_FILES_DIR, 'pilot_proceed_compliant.json')) def pilot_proceed_noncompliant_test(self): - """Generate a report for the non-compliant test with a pilot device""" + """Generate a report for proceed/non-compliant test with a pilot device""" - # Generate a compliant report based on the - # 'report_noncompliant_pilot.json' file + # Generate the report self.create_report(os.path.join(TEST_FILES_DIR, 'pilot_proceed_noncompliant.json')) def pilot_do_not_proceed_noncompliant_test(self): - """Generate a report for the non-compliant test with a pilot device""" + """Report for do not proceed/non-compliant test with a pilot device""" - # Generate a compliant report based on the - # 'report_noncompliant_pilot.json' file + # Generate the report self.create_report(os.path.join(TEST_FILES_DIR, 'pilot_do_not_proceed_noncompliant.json')) + # Generate formatted reports for each report generated from # the test containers. # Not a unit test but can't run from within the test module container and must From 1e6bde3c84a922ee408eed60533ae42b0008ee79 Mon Sep 17 00:00:00 2001 From: MariusBaldovin Date: Wed, 12 Feb 2025 10:32:22 +0000 Subject: [PATCH 6/7] fix the overlapping text --- resources/report/test_report_styles.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/report/test_report_styles.css b/resources/report/test_report_styles.css index 8cc4ac5cd..90d7cb3d8 100644 --- a/resources/report/test_report_styles.css +++ b/resources/report/test_report_styles.css @@ -457,7 +457,7 @@ position: absolute; font-size: 12px; margin-top: 12px; - max-width: 300px; + max-width: 185px; font-weight: normal; align-items: center; text-overflow: ellipsis; @@ -466,7 +466,7 @@ } .result-test-description { - max-width: 380px; + max-width: 300px; } .result-test-result-error { From 24a7889c7d07f8b8227551c4d4959565ca6cdbf4 Mon Sep 17 00:00:00 2001 From: MariusBaldovin Date: Wed, 12 Feb 2025 11:09:56 +0000 Subject: [PATCH 7/7] restored package-lock.json --- modules/ui/package-lock.json | 262 +++++++++++++++++++++++++---------- 1 file changed, 191 insertions(+), 71 deletions(-) diff --git a/modules/ui/package-lock.json b/modules/ui/package-lock.json index 1993d3a21..6d6356513 100644 --- a/modules/ui/package-lock.json +++ b/modules/ui/package-lock.json @@ -569,34 +569,6 @@ "typescript": ">=5.4 <5.6" } }, - "node_modules/@angular/compiler-cli/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", - "dev": true, - "dependencies": { - "readdirp": "^4.0.1" - }, - "engines": { - "node": ">= 14.16.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@angular/compiler-cli/node_modules/readdirp": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", - "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", - "dev": true, - "engines": { - "node": ">= 14.18.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@angular/core": { "version": "18.2.13", "resolved": "https://registry.npmjs.org/@angular/core/-/core-18.2.13.tgz", @@ -5909,39 +5881,18 @@ "dev": true }, "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "readdirp": "^4.0.1" }, "engines": { - "node": ">= 8.10.0" + "node": ">= 14.16.0" }, "funding": { "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" } }, "node_modules/chownr": { @@ -9335,6 +9286,30 @@ "concat-map": "0.0.1" } }, + "node_modules/karma/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/karma/node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -9352,6 +9327,18 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/karma/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/karma/node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -9373,6 +9360,30 @@ "node": "*" } }, + "node_modules/karma/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/karma/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/karma/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -12406,27 +12417,16 @@ } }, "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/readdirp/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", + "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", "dev": true, "engines": { - "node": ">=8.6" + "node": ">= 14.18.0" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/reflect-metadata": { @@ -12866,6 +12866,66 @@ } } }, + "node_modules/sass/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/sass/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/sass/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/sass/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/sax": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", @@ -15206,6 +15266,30 @@ } } }, + "node_modules/webpack-dev-server/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/webpack-dev-server/node_modules/glob": { "version": "10.4.5", "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", @@ -15226,6 +15310,18 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/webpack-dev-server/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", @@ -15250,6 +15346,30 @@ } } }, + "node_modules/webpack-dev-server/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/webpack-dev-server/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/webpack-dev-server/node_modules/rimraf": { "version": "5.0.10", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz",