I can use commands

This commit is contained in:
2025-10-24 22:58:48 +02:00
parent 0f5fc696f0
commit 063a89f143
5 changed files with 263 additions and 17 deletions

View File

@@ -1,26 +1,53 @@
import pytest
from fasthtml.fastapp import fast_app
from myfasthtml.controls.button import mk_button
from myfasthtml.core.commands import Command
from myfasthtml.core.testclient import MyTestClient
from myfasthtml.core.commands import Command, CommandsManager
from myfasthtml.core.testclient import MyTestClient, TestableElement
def new_value(value):
return value
command = Command('test', 'TestingCommand', new_value, "this is my new value")
def test_i_can_trigger_a_command():
@pytest.fixture()
def user():
test_app, rt = fast_app(default_hdrs=False)
user = MyTestClient(test_app)
return user
@pytest.fixture()
def rt(user):
return user.app.route
def test_i_can_trigger_a_command(user):
command = Command('test', 'TestingCommand', new_value, "this is my new value")
testable = TestableElement(user, mk_button('button', command))
testable.click()
assert user.get_content() == "this is my new value"
def test_error_is_raised_when_command_is_not_found(user):
command = Command('test', 'TestingCommand', new_value, "this is my new value")
CommandsManager.reset()
testable = TestableElement(user, mk_button('button', command))
with pytest.raises(ValueError) as exc_info:
testable.click()
assert "not found." in str(exc_info.value)
def test_i_can_play_a_complex_scenario(user, rt):
command = Command('test', 'TestingCommand', new_value, "this is my new value")
@rt('/')
def get(): return mk_button('button', command)
user.open("/")
user.should_see("button")
b = user.find_element("button")
b.click()
user.find_element("button").click()
user.should_see("this is my new value")

View File

@@ -0,0 +1,69 @@
import pytest
from fasthtml.components import Div
from fasthtml.fastapp import fast_app
from myfasthtml.core.testclient import MyTestClient, TestableElement, MyFT
def test_i_can_create_testable_element_from_ft():
ft = Div("hello world", id="test")
testable_element = TestableElement(None, ft)
assert testable_element.ft == ft
assert testable_element.html_fragment == '<div id="test">hello world</div>'
def test_i_can_create_testable_element_from_str():
ft = '<div id="test">hello world</div>'
testable_element = TestableElement(None, ft)
assert testable_element.ft == MyFT('div', {'id': 'test'})
assert testable_element.html_fragment == '<div id="test">hello world</div>'
def test_i_can_create_testable_element_from_beautifulsoup_element():
ft = '<div id="test">hello world</div>'
from bs4 import BeautifulSoup
tag = BeautifulSoup(ft, 'html.parser').div
testable_element = TestableElement(None, tag)
assert testable_element.ft == MyFT('div', {'id': 'test'})
assert testable_element.html_fragment == '<div id="test">hello world</div>'
def test_i_cannot_create_testable_element_from_other_type():
with pytest.raises(ValueError) as exc_info:
TestableElement(None, 123)
assert str(exc_info.value) == "Invalid source '123' for TestableElement."
def test_i_can_click():
test_app, rt = fast_app(default_hdrs=False)
client = MyTestClient(test_app)
ft = Div(
hx_post="/search",
hx_target="#results",
hx_swap="innerHTML",
hx_vals='{"attr": "attr_value"}'
)
testable_element = TestableElement(client, ft)
@rt('/search')
def post(hx_target: str, hx_swap: str, attr: str): # hx_post is used to the Verb. It's not a parameter
return f"received {hx_target=}, {hx_swap=}, {attr=}"
testable_element.click()
assert client.get_content() == "received hx_target='#results', hx_swap='innerHTML', attr='attr_value'"
def test_i_cannot_test_when_not_clickable():
test_app, rt = fast_app(default_hdrs=False)
client = MyTestClient(test_app)
ft = Div("hello world")
testable_element = TestableElement(client, ft)
with pytest.raises(ValueError) as exc_info:
testable_element.click()
assert str(exc_info.value) == "The <div> element has no HTMX verb attribute (e.g., hx_get, hx_post) to define a URL."