#!/usr/bin/env python3 """ Test HTML Rendering in Notes Field This script tests that the notes field HTML content is properly rendered in the output HTML file instead of being escaped. """ import asyncio import json import logging import sys import tempfile from pathlib import Path import os # Add the current directory to the path so we can import modules sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from snapshot_downloader import SnapshotDownloader class HTMLRenderingTester: """Test class for HTML rendering functionality.""" def __init__(self): """Initialize the tester.""" self.logger = logging.getLogger(__name__) def test_notes_html_rendering(self): """Test that HTML in notes field is properly rendered.""" print("=" * 60) print("TEST: HTML Rendering in Notes Field") print("=" * 60) with tempfile.TemporaryDirectory() as temp_dir: downloader = SnapshotDownloader(output_dir=temp_dir) print("1. Testing snapshot with HTML content in notes...") # Create mock snapshot with HTML content in notes mock_snapshot = { "id": "test_html_rendering", "type": "Snapshot", "code": "Snapshot", "child": { "forename": "Test", "surname": "Child" }, "author": { "forename": "Test", "surname": "Teacher" }, "startTime": "2024-01-15T10:30:00", "notes": """

This is a bold statement about the child's progress.


The child demonstrated excellent skills in:

• Communication

• Problem solving


Important note: Continue encouraging creative play.

Next steps: Focus on fine motor skills development.

""", "frameworkIndicatorCount": 15, "signed": False } # Generate HTML for the snapshot html_content = downloader.format_snapshot_html(mock_snapshot) print("2. Checking HTML content rendering...") # Check that HTML tags are NOT escaped (should be rendered) within notes-content if 'notes-content">

' in html_content or 'notes-content">' in html_content: print(" ✅ HTML paragraph tags are rendered (not escaped)") else: print(" ❌ HTML paragraph tags are escaped instead of rendered") # Debug output to see what we actually got start = html_content.find('notes-content') if start != -1: sample = html_content[start:start+150] print(f" Debug - Found: {sample}") return False if "bold" in html_content: print(" ✅ HTML strong tags are rendered (not escaped)") else: print(" ❌ HTML strong tags are escaped instead of rendered") return False if "excellent" in html_content: print(" ✅ HTML emphasis tags are rendered (not escaped)") else: print(" ❌ HTML emphasis tags are escaped instead of rendered") return False if 'style="color: rgb(255, 0, 0);"' in html_content: print(" ✅ Inline CSS styles are preserved") else: print(" ❌ Inline CSS styles are not preserved") return False print("\n3. Testing complete HTML file generation...") # Generate complete HTML file mock_snapshots = [mock_snapshot] html_file = downloader.generate_html_file( mock_snapshots, "2024-01-01", "2024-01-31" ) if html_file.exists(): print(" ✅ HTML file created successfully") # Read and check file content with open(html_file, 'r', encoding='utf-8') as f: file_content = f.read() # Check for proper HTML structure if 'class="notes-content"' in file_content: print(" ✅ Notes content wrapper class present") else: print(" ❌ Notes content wrapper class missing") return False # Check that HTML content is rendered in the file if "

This is a bold statement" in file_content: print(" ✅ HTML content properly rendered in file") else: print(" ❌ HTML content not properly rendered in file") print(" Debug: Looking for HTML content in file...") # Show a sample of the content for debugging start = file_content.find('notes-content') if start != -1: sample = file_content[start:start+200] print(f" Sample content: {sample}") return False # Check for CSS styles that handle HTML content if ".notes-content" in file_content: print(" ✅ CSS styles for notes content included") else: print(" ❌ CSS styles for notes content missing") return False else: print(" ❌ HTML file was not created") return False print("\n4. Testing XSS safety with potentially dangerous content...") # Test with potentially dangerous content to ensure basic safety dangerous_snapshot = { "id": "test_xss_safety", "type": "Snapshot", "startTime": "2024-01-15T10:30:00", "notes": '

Safe content

More safe content

', } dangerous_html = downloader.format_snapshot_html(dangerous_snapshot) # The script tag should still be present (we're not sanitizing, just rendering) # But we should document this as a security consideration if '