""" End-to-end test for HTML links in EreaderLayoutManager. This test mimics exactly what the dreader application does: 1. Load HTML with links via parse_html_string 2. Create an EreaderLayoutManager 3. Render a page 4. Query for interactive elements This should reveal if links are actually interactive after full rendering. """ import unittest from pyWebLayout.io.readers.html_extraction import parse_html_string from pyWebLayout.layout.ereader_manager import EreaderLayoutManager from pyWebLayout.abstract.inline import LinkedWord from pyWebLayout.concrete.functional import LinkText class TestHTMLLinksInEreader(unittest.TestCase): """Test HTML link interactivity in the full ereader pipeline.""" def test_settings_overlay_links_are_interactive(self): """Test that settings overlay HTML creates interactive links.""" # This is realistic settings overlay HTML html = '''

Settings

Back to Library

Font Size: [-] [+]

''' # Step 1: Parse HTML to blocks blocks = parse_html_string(html) # Verify LinkedWords were created all_linked_words = [] for block in blocks: if hasattr(block, 'words'): for word in block.words: if isinstance(word, LinkedWord): all_linked_words.append(word) self.assertGreater(len(all_linked_words), 0, "Should create LinkedWords from HTML") print(f"\n Created {len(all_linked_words)} LinkedWords from HTML") # Step 2: Create EreaderLayoutManager (like the dreader app does) page_size = (400, 600) manager = EreaderLayoutManager( blocks=blocks, page_size=page_size, document_id="test_settings" ) # Step 3: Get the rendered page page = manager.get_current_page() self.assertIsNotNone(page) # Step 4: Render to image rendered_image = page.render() self.assertIsNotNone(rendered_image) print(f" Rendered page: {rendered_image.size}") # Step 5: Find all interactive elements by scanning the page # This is the CRITICAL test - are there LinkText objects in the page? interactive_elements = [] # Scan through all children of the page if hasattr(page, '_children'): for child in page._children: # Check if child is a Line if hasattr(child, '_text_objects'): for text_obj in child._text_objects: if isinstance(text_obj, LinkText): interactive_elements.append({ 'type': 'LinkText', 'text': text_obj._text, 'location': text_obj.link.location, 'is_interactive': hasattr(text_obj, 'execute') }) print(f" Found {len(interactive_elements)} LinkText objects in rendered page") for elem in interactive_elements: print(f" - '{elem['text']}' -> {elem['location']}") # THIS IS THE KEY ASSERTION self.assertGreater(len(interactive_elements), 0, "Settings overlay should have interactive LinkText objects after rendering!") # Verify the expected links are present locations = {elem['location'] for elem in interactive_elements} self.assertIn("action:back_to_library", locations, "Should find 'Back to Library' link") self.assertIn("setting:font_decrease", locations, "Should find font decrease link") self.assertIn("setting:font_increase", locations, "Should find font increase link") def test_query_point_detects_links(self): """Test that query_point can detect LinkText objects.""" html = '

Click here to test.

' blocks = parse_html_string(html) manager = EreaderLayoutManager( blocks=blocks, page_size=(400, 200), document_id="test_query" ) page = manager.get_current_page() page.render() # Try to query various points on the page # We don't know exact coordinates, so scan a grid found_link = False for y in range(20, 100, 10): for x in range(20, 380, 20): result = page.query_point((x, y)) if result and result.is_interactive: print(f"\n Found interactive element at ({x}, {y})") print(f" Type: {result.object_type}") print(f" Link target: {result.link_target}") print(f" Text: {result.text}") found_link = True self.assertEqual(result.link_target, "action:test") break if found_link: break self.assertTrue(found_link, "Should be able to detect link via query_point somewhere on the page") if __name__ == '__main__': unittest.main()