I can bind elements

This commit is contained in:
2025-11-01 23:44:18 +01:00
parent 991a6f07ff
commit aaba6a5468
14 changed files with 463 additions and 109 deletions

View File

@@ -10,7 +10,7 @@ from fasthtml.common import FastHTML
from starlette.responses import Response
from starlette.testclient import TestClient
from myfasthtml.core.commands import mount_commands
from myfasthtml.core.utils import mount_utils
verbs = {
'hx_get': 'GET',
@@ -130,8 +130,15 @@ class TestableElement:
if data is not None:
headers['Content-Type'] = 'application/x-www-form-urlencoded'
bag_to_use = data
elif json_data is not None:
headers['Content-Type'] = 'application/json'
bag_to_use = json_data
else:
# default to json_data
headers['Content-Type'] = 'application/json'
json_data = {}
bag_to_use = json_data
# .props contains the kwargs passed to the object (e.g., hx_post="/url")
element_attrs = self.my_ft.attrs or {}
@@ -151,11 +158,10 @@ class TestableElement:
elif key == 'hx_vals':
# hx_vals defines the JSON body, if not already provided by the test
if json_data is None:
if isinstance(value, str):
json_data = json.loads(value)
elif isinstance(value, dict):
json_data = value
if isinstance(value, str):
bag_to_use |= json.loads(value)
elif isinstance(value, dict):
bag_to_use |= value
elif key.startswith('hx_'):
# Any other hx_* attribute is converted to an HTTP header
@@ -924,7 +930,7 @@ class MyTestClient:
self.parent_levels = parent_levels
# make sure that the commands are mounted
mount_commands(self.app)
mount_utils(self.app)
def open(self, path: str) -> Self:
"""
@@ -952,6 +958,8 @@ class MyTestClient:
def send_request(self, method: str, url: str, headers: dict = None, data=None, json_data=None):
if json_data is not None:
json_data['session'] = self._session
if data is not None:
data['session'] = self._session
res = self.client.request(
method,
@@ -1088,7 +1096,7 @@ class MyTestClient:
f"No element found matching selector '{selector}'."
)
elif len(results) == 1:
return TestableElement(self, results[0], results[0].name)
return self._testable_element_factory(results[0])
else:
raise AssertionError(
f"Found {len(results)} elements matching selector '{selector}'. Expected exactly 1."
@@ -1148,6 +1156,12 @@ class MyTestClient:
self._soup = BeautifulSoup(content, 'html.parser')
return self
def _testable_element_factory(self, elt):
if elt.name == "input":
return TestableInput(self, elt)
else:
return TestableElement(self, elt, elt.name)
@staticmethod
def _find_visible_text_element(soup, text: str):
"""