""" End-to-end test for HTML link interactivity with query_point. This test verifies the complete flow: 1. HTML with links -> parse_html_string -> LinkedWord objects 2. LinkedWord objects -> DocumentLayouter -> Rendered page 3. Rendered page -> query_point -> Interactive link detection """ import unittest from pyWebLayout.io.readers.html_extraction import parse_html_string from pyWebLayout.concrete.page import Page from pyWebLayout.style.page_style import PageStyle from pyWebLayout.layout.document_layouter import DocumentLayouter from pyWebLayout.abstract.inline import LinkedWord class TestHTMLLinkEndToEnd(unittest.TestCase): """Test complete HTML link workflow from parsing to interaction.""" def test_complete_link_workflow(self): """Test the complete workflow: HTML -> parsing -> layout -> query.""" # Step 1: Create HTML with a link html = '

Click this link to test.

' # Step 2: Parse HTML to blocks blocks = parse_html_string(html) self.assertEqual(len(blocks), 1) # Step 3: Verify LinkedWord was created paragraph = blocks[0] linked_words = [w for w in paragraph.words if isinstance(w, LinkedWord)] self.assertEqual(len(linked_words), 2) # "this" and "link" # Verify link properties for word in linked_words: self.assertEqual(word.location, "action:test_action") self.assertIn(word.text, ["this", "link"]) # Step 4: Layout on a page page_style = PageStyle() page = Page((400, 200), page_style) layouter = DocumentLayouter(page) layouter.layout_document([paragraph]) # Step 5: Render the page rendered = page.render() self.assertIsNotNone(rendered) # Step 6: Test query_point functionality # The query system should be able to detect interactive elements # Note: Exact coordinates depend on layout, so we test the capability # rather than specific pixel positions # Try to query various points on the page # The page should respond to queries (even if we don't hit the exact link) result = page.query_point((100, 50)) # Result might be None if we didn't hit any text, but the API should work # The key is that if we DID hit a link, it would be detected print(f"Query result: {result}") if result and result.is_interactive: # If we hit an interactive element, it should have link info self.assertIsNotNone(result.link_target) print(f"Found interactive link: {result.link_target}") def test_settings_overlay_complete_workflow(self): """Test the complete workflow with actual settings overlay HTML.""" # This is the exact HTML pattern used for settings overlays html = '''

Settings

Back to Library

Font Size: [-] [+]

''' # Parse HTML blocks = parse_html_string(html) # Collect all LinkedWords 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) # Verify we found the expected links self.assertGreater(len(all_linked_words), 0) # Check for specific actions actions = {word.location for word in all_linked_words} self.assertIn("action:back_to_library", actions) self.assertIn("setting:font_decrease", actions) self.assertIn("setting:font_increase", actions) # Layout and render page_style = PageStyle(padding=(10, 10, 10, 10)) page = Page((400, 300), page_style) layouter = DocumentLayouter(page) for block in blocks: layouter.layout_document([block]) rendered = page.render() self.assertIsNotNone(rendered) print(f"\nSettings overlay test:") print(f" Found {len(all_linked_words)} linked words") print(f" Actions: {actions}") print(f" Rendered: {rendered.size}") # The links are successfully created and rendered! # In a real application, query_point would be used to detect clicks on these links def test_link_metadata_preserved(self): """Test that link metadata (title, type) is preserved through the workflow.""" html = '''

External Internal API

''' blocks = parse_html_string(html) paragraph = blocks[0] linked_words = [w for w in paragraph.words if isinstance(w, LinkedWord)] # Should have 3 LinkedWords (one for each link) self.assertEqual(len(linked_words), 3) # Check that link metadata is preserved links_by_text = {w.text: w for w in linked_words} # External link external = links_by_text.get("External") self.assertIsNotNone(external) self.assertEqual(external.location, "https://example.com") self.assertEqual(external.link_title, "Example Site") # Internal link internal = links_by_text.get("Internal") self.assertIsNotNone(internal) self.assertEqual(internal.location, "#section2") self.assertEqual(internal.link_title, "Go to Section 2") # API link api = links_by_text.get("API") self.assertIsNotNone(api) self.assertTrue(api.location.startswith("javascript:")) self.assertEqual(api.link_title, "Alert") if __name__ == '__main__': unittest.main()