import pytest from fasthtml.components import Div from fasthtml.fastapp import fast_app from myfasthtml.core.testclient import MyTestClient, TestableElement def test_i_can_open_a_page(): test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return "hello world" client.open("/") assert client.get_content() == "hello world" def test_i_can_open_a_page_when_html(): test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return Div("hello world") client.open("/") assert client.get_content() == ' \n \n \n FastHTML page\n \n \n \n
hello world
\n \n \n' def test_i_cannot_open_a_page_not_defined(): test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) with pytest.raises(AssertionError) as exc_info: client.open("/not_found") assert str(exc_info.value) == "Failed to open '/not_found'. status code=404 : reason='404 Not Found'" def test_i_can_see_text_in_plain_response(): """Test that should_see() works with plain text responses.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return "hello world" client.open("/").should_see("hello world") def test_i_can_see_text_in_html_response(): """Test that should_see() extracts visible text from HTML responses.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return "

Welcome

This is a test

" client.open("/").should_see("Welcome").should_see("This is a test") def test_i_can_see_text_ignoring_html_tags(): """Test that should_see() searches in visible text only, not in HTML tags.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return '
Content
' # Should find the visible text client.open("/").should_see("Content") # Should NOT find text that's only in attributes/tags with pytest.raises(AssertionError) as exc_info: client.should_see("container") assert "Expected to see 'container' in page content but it was not found" in str(exc_info.value) def test_i_cannot_see_text_that_is_not_present(): """Test that should_see() raises AssertionError when text is not found.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return "hello world" with pytest.raises(AssertionError) as exc_info: client.open("/").should_see("goodbye") assert "Expected to see 'goodbye' in page content but it was not found" in str(exc_info.value) assert "hello world" in str(exc_info.value) def test_i_cannot_call_should_see_without_opening_page(): """Test that should_see() raises ValueError if no page has been opened.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) with pytest.raises(ValueError) as exc_info: client.should_see("anything") assert str(exc_info.value) == "No page content available. Call open() before should_see()." def test_i_can_verify_text_is_not_present(): """Test that should_not_see() works when text is absent.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return "hello world" client.open("/").should_not_see("goodbye") def test_i_cannot_use_should_not_see_when_text_is_present(): """Test that should_not_see() raises AssertionError when text is found.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return "hello world" with pytest.raises(AssertionError) as exc_info: client.open("/").should_not_see("hello") error_message = str(exc_info.value) assert "Expected NOT to see 'hello' in page content but it was found" in error_message def test_i_cannot_call_should_not_see_without_opening_page(): """Test that should_not_see() raises ValueError if no page has been opened.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) with pytest.raises(ValueError) as exc_info: client.should_not_see("anything") assert str(exc_info.value) == "No page content available. Call open() before should_not_see()." def test_i_can_chain_multiple_assertions(): """Test that assertions can be chained together.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return "

Welcome

Content here

" # Chain multiple assertions client.open("/").should_see("Welcome").should_see("Content").should_not_see("Error") def test_i_can_see_element_context_when_text_should_not_be_seen(): """Test that the HTML element containing the text is displayed with parent context.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return '

forbidden text

' with pytest.raises(AssertionError) as exc_info: client.open("/").should_not_see("forbidden text") error_message = str(exc_info.value) assert "Found in:" in error_message assert '

forbidden text

' in error_message assert '
' in error_message def test_i_can_configure_parent_levels_in_constructor(): """Test that parent_levels parameter controls the number of parent levels shown.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app, parent_levels=2) @rt('/') def get(): return '

error

' with pytest.raises(AssertionError) as exc_info: client.open("/").should_not_see("error") error_message = str(exc_info.value) assert '

error

' in error_message assert '
' in error_message assert '
' in error_message def test_i_can_find_text_in_nested_elements(): """Test that the smallest element containing the text is found in nested structures.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return '

nested text

' with pytest.raises(AssertionError) as exc_info: client.open("/").should_not_see("nested text") error_message = str(exc_info.value) # Should find the

element, not the outer

assert '

nested text

' in error_message def test_i_can_find_fragmented_text_across_tags(): """Test that text fragmented across multiple tags is correctly found.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return '

hello world

' with pytest.raises(AssertionError) as exc_info: client.open("/").should_not_see("hello world") error_message = str(exc_info.value) # Should find the parent

element that contains the full text assert '

' in error_message def test_i_do_not_find_text_in_html_attributes(): """Test that text in HTML attributes is not considered as visible text.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return '

Success
' # "error" is in attributes but not in visible text client.open("/").should_not_see("error") # "Success" is in visible text with pytest.raises(AssertionError): client.should_not_see("Success") @pytest.mark.parametrize("selector,expected_tag", [ ("#unique-id", '
div", '
'), ('[data-author*="john"]', ' Home About
Content
''' element = client.open("/").find_element(selector) assert element is not None assert isinstance(element, TestableElement) assert expected_tag in element.html_fragment def test_i_cannot_find_element_when_none_exists(): """Test that find_element raises AssertionError when no element matches.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return '

Content

' with pytest.raises(AssertionError) as exc_info: client.open("/").find_element("#non-existent") assert "No element found matching selector '#non-existent'" in str(exc_info.value) def test_i_cannot_find_element_when_multiple_exist(): """Test that find_element raises AssertionError when multiple elements match.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) @rt('/') def get(): return '

First

Second

Third

' with pytest.raises(AssertionError) as exc_info: client.open("/").find_element(".text") error_message = str(exc_info.value) assert "Found 3 elements matching selector '.text'" in error_message assert "Expected exactly 1" in error_message def test_i_cannot_call_find_element_without_opening_page(): """Test that find_element raises ValueError if no page has been opened.""" test_app, rt = fast_app(default_hdrs=False) client = MyTestClient(test_app) with pytest.raises(ValueError) as exc_info: client.find_element("#any-selector") assert str(exc_info.value) == "No page content available. Call open() before find_element()."