Added unit tests for Layout.py
This commit is contained in:
@@ -4,9 +4,8 @@ import shutil
|
||||
import pytest
|
||||
from fasthtml.components import *
|
||||
|
||||
from myfasthtml.controls.Layout import Layout, LayoutState
|
||||
from myfasthtml.controls.UserProfile import UserProfile
|
||||
from myfasthtml.test.matcher import matches, find, Contains, NotStr, TestObject
|
||||
from myfasthtml.controls.Layout import Layout
|
||||
from myfasthtml.test.matcher import matches, find, Contains, find_one, TestIcon, TestScript
|
||||
from .conftest import root_instance
|
||||
|
||||
|
||||
@@ -17,219 +16,219 @@ def cleanup_db():
|
||||
|
||||
class TestLayoutBehaviour:
|
||||
"""Tests for Layout behavior and logic."""
|
||||
|
||||
|
||||
def test_i_can_create_layout(self, root_instance):
|
||||
"""Test basic layout creation with app_name."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
|
||||
|
||||
assert layout is not None
|
||||
assert layout.app_name == "Test App"
|
||||
assert layout._state is not None
|
||||
|
||||
|
||||
def test_i_can_set_main_content(self, root_instance):
|
||||
"""Test setting main content area."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
content = Div("Main content")
|
||||
|
||||
|
||||
result = layout.set_main(content)
|
||||
|
||||
|
||||
assert layout._main_content == content
|
||||
assert result == layout # Should return self for chaining
|
||||
|
||||
|
||||
def test_i_can_set_footer_content(self, root_instance):
|
||||
"""Test setting footer content."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
content = Div("Footer content")
|
||||
|
||||
|
||||
layout.set_footer(content)
|
||||
|
||||
|
||||
assert layout._footer_content == content
|
||||
|
||||
|
||||
def test_i_can_add_content_to_left_drawer(self, root_instance):
|
||||
"""Test adding content to left drawer."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
content = Div("Left drawer content", id="drawer_item")
|
||||
|
||||
|
||||
layout.left_drawer.add(content)
|
||||
|
||||
|
||||
drawer_content = layout.left_drawer.get_content()
|
||||
assert None in drawer_content
|
||||
assert content in drawer_content[None]
|
||||
|
||||
|
||||
def test_i_can_add_content_to_right_drawer(self, root_instance):
|
||||
"""Test adding content to right drawer."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
content = Div("Right drawer content", id="drawer_item")
|
||||
|
||||
|
||||
layout.right_drawer.add(content)
|
||||
|
||||
|
||||
drawer_content = layout.right_drawer.get_content()
|
||||
assert None in drawer_content
|
||||
assert content in drawer_content[None]
|
||||
|
||||
|
||||
def test_i_can_add_content_to_header_left(self, root_instance):
|
||||
"""Test adding content to left side of header."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
content = Div("Header left content", id="header_item")
|
||||
|
||||
|
||||
layout.header_left.add(content)
|
||||
|
||||
|
||||
header_content = layout.header_left.get_content()
|
||||
assert None in header_content
|
||||
assert content in header_content[None]
|
||||
|
||||
|
||||
def test_i_can_add_content_to_header_right(self, root_instance):
|
||||
"""Test adding content to right side of header."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
content = Div("Header right content", id="header_item")
|
||||
|
||||
|
||||
layout.header_right.add(content)
|
||||
|
||||
|
||||
header_content = layout.header_right.get_content()
|
||||
assert None in header_content
|
||||
assert content in header_content[None]
|
||||
|
||||
|
||||
def test_i_can_add_grouped_content(self, root_instance):
|
||||
"""Test adding content with custom groups."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
group_name = "navigation"
|
||||
content1 = Div("Nav item 1", id="nav1")
|
||||
content2 = Div("Nav item 2", id="nav2")
|
||||
|
||||
|
||||
layout.left_drawer.add(content1, group=group_name)
|
||||
layout.left_drawer.add(content2, group=group_name)
|
||||
|
||||
|
||||
drawer_content = layout.left_drawer.get_content()
|
||||
assert group_name in drawer_content
|
||||
assert content1 in drawer_content[group_name]
|
||||
assert content2 in drawer_content[group_name]
|
||||
|
||||
|
||||
def test_i_cannot_add_duplicate_content(self, root_instance):
|
||||
"""Test that content with same ID is not added twice."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
content = Div("Content", id="unique_id")
|
||||
|
||||
|
||||
layout.left_drawer.add(content)
|
||||
layout.left_drawer.add(content) # Try to add again
|
||||
|
||||
|
||||
drawer_content = layout.left_drawer.get_content()
|
||||
# Content should appear only once
|
||||
assert drawer_content[None].count(content) == 1
|
||||
|
||||
|
||||
def test_i_can_toggle_left_drawer(self, root_instance):
|
||||
"""Test toggling left drawer open/closed."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
|
||||
|
||||
# Initially open
|
||||
assert layout._state.left_drawer_open is True
|
||||
|
||||
|
||||
# Toggle to close
|
||||
layout.toggle_drawer("left")
|
||||
assert layout._state.left_drawer_open is False
|
||||
|
||||
|
||||
# Toggle to open
|
||||
layout.toggle_drawer("left")
|
||||
assert layout._state.left_drawer_open is True
|
||||
|
||||
|
||||
def test_i_can_toggle_right_drawer(self, root_instance):
|
||||
"""Test toggling right drawer open/closed."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
|
||||
|
||||
# Initially open
|
||||
assert layout._state.right_drawer_open is True
|
||||
|
||||
|
||||
# Toggle to close
|
||||
layout.toggle_drawer("right")
|
||||
assert layout._state.right_drawer_open is False
|
||||
|
||||
|
||||
# Toggle to open
|
||||
layout.toggle_drawer("right")
|
||||
assert layout._state.right_drawer_open is True
|
||||
|
||||
|
||||
def test_i_can_update_left_drawer_width(self, root_instance):
|
||||
"""Test updating left drawer width."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
new_width = 300
|
||||
|
||||
|
||||
layout.update_drawer_width("left", new_width)
|
||||
|
||||
|
||||
assert layout._state.left_drawer_width == new_width
|
||||
|
||||
|
||||
def test_i_can_update_right_drawer_width(self, root_instance):
|
||||
"""Test updating right drawer width."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
new_width = 400
|
||||
|
||||
|
||||
layout.update_drawer_width("right", new_width)
|
||||
|
||||
|
||||
assert layout._state.right_drawer_width == new_width
|
||||
|
||||
|
||||
def test_i_cannot_set_drawer_width_below_minimum(self, root_instance):
|
||||
"""Test that drawer width is constrained to minimum 150px."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
|
||||
|
||||
layout.update_drawer_width("left", 100) # Try to set below minimum
|
||||
|
||||
|
||||
assert layout._state.left_drawer_width == 150 # Should be clamped to min
|
||||
|
||||
|
||||
def test_i_cannot_set_drawer_width_above_maximum(self, root_instance):
|
||||
"""Test that drawer width is constrained to maximum 600px."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
|
||||
|
||||
layout.update_drawer_width("right", 800) # Try to set above maximum
|
||||
|
||||
|
||||
assert layout._state.right_drawer_width == 600 # Should be clamped to max
|
||||
|
||||
|
||||
def test_i_cannot_toggle_invalid_drawer_side(self, root_instance):
|
||||
"""Test that toggling invalid drawer side raises ValueError."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
|
||||
|
||||
with pytest.raises(ValueError, match="Invalid drawer side"):
|
||||
layout.toggle_drawer("invalid")
|
||||
|
||||
|
||||
def test_i_cannot_update_invalid_drawer_width(self, root_instance):
|
||||
"""Test that updating invalid drawer side raises ValueError."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
|
||||
|
||||
with pytest.raises(ValueError, match="Invalid drawer side"):
|
||||
layout.update_drawer_width("invalid", 250)
|
||||
|
||||
|
||||
def test_layout_state_has_correct_defaults(self, root_instance):
|
||||
"""Test that LayoutState initializes with correct default values."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
state = layout._state
|
||||
|
||||
|
||||
assert state.left_drawer_open is True
|
||||
assert state.right_drawer_open is True
|
||||
assert state.left_drawer_width == 250
|
||||
assert state.right_drawer_width == 250
|
||||
|
||||
|
||||
def test_layout_is_single_instance(self, root_instance):
|
||||
"""Test that Layout behaves as SingleInstance (same ID returns same instance)."""
|
||||
layout1 = Layout(root_instance, app_name="Test App", _id="my_layout")
|
||||
layout2 = Layout(root_instance, app_name="Test App", _id="my_layout")
|
||||
|
||||
|
||||
# Should be the same instance
|
||||
assert layout1 is layout2
|
||||
|
||||
|
||||
def test_commands_are_created(self, root_instance):
|
||||
"""Test that Layout creates necessary commands."""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
|
||||
|
||||
# Test toggle commands
|
||||
left_toggle_cmd = layout.commands.toggle_drawer("left")
|
||||
assert left_toggle_cmd is not None
|
||||
assert left_toggle_cmd.id is not None
|
||||
|
||||
|
||||
right_toggle_cmd = layout.commands.toggle_drawer("right")
|
||||
assert right_toggle_cmd is not None
|
||||
assert right_toggle_cmd.id is not None
|
||||
|
||||
|
||||
# Test width update commands
|
||||
left_width_cmd = layout.commands.update_drawer_width("left")
|
||||
assert left_width_cmd is not None
|
||||
assert left_width_cmd.id is not None
|
||||
|
||||
|
||||
right_width_cmd = layout.commands.update_drawer_width("right")
|
||||
assert right_width_cmd is not None
|
||||
assert right_width_cmd.id is not None
|
||||
@@ -237,8 +236,12 @@ class TestLayoutBehaviour:
|
||||
|
||||
class TestLayoutRender:
|
||||
"""Tests for Layout HTML rendering."""
|
||||
|
||||
def test_empty_layout_is_rendered(self, root_instance):
|
||||
|
||||
@pytest.fixture
|
||||
def layout(self, root_instance):
|
||||
return Layout(root_instance, app_name="Test App")
|
||||
|
||||
def test_empty_layout_is_rendered(self, layout):
|
||||
"""Test that Layout renders with all main structural sections.
|
||||
|
||||
Why these elements matter:
|
||||
@@ -246,101 +249,97 @@ class TestLayoutRender:
|
||||
- _id: Essential for layout identification and resizer initialization
|
||||
- cls="mf-layout": Root CSS class for layout styling
|
||||
"""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
|
||||
expected = Div(
|
||||
Header(),
|
||||
Div(),
|
||||
Main(),
|
||||
Div(),
|
||||
Footer(),
|
||||
Script(),
|
||||
_id=layout._id,
|
||||
cls="mf-layout"
|
||||
Header(),
|
||||
Div(), # left drawer
|
||||
Main(),
|
||||
Div(), # right drawer
|
||||
Footer(),
|
||||
Script(),
|
||||
_id=layout._id,
|
||||
cls="mf-layout"
|
||||
)
|
||||
|
||||
|
||||
assert matches(layout.render(), expected)
|
||||
|
||||
def test_header_with_drawer_icons_is_rendered(self, root_instance):
|
||||
|
||||
def test_header_has_two_sides(self, layout):
|
||||
"""Test that there is a left and right header section."""
|
||||
header = find_one(layout.render(), Header(cls="mf-layout-header"))
|
||||
|
||||
expected = Header(
|
||||
Div(id=f"{layout._id}_hl"),
|
||||
Div(id=f"{layout._id}_hr"),
|
||||
)
|
||||
|
||||
assert matches(header, expected)
|
||||
|
||||
def test_footer_has_two_sides(self, layout):
|
||||
"""Test that there is a left and right footer section."""
|
||||
footer = find_one(layout.render(), Footer(cls=Contains("mf-layout-footer")))
|
||||
|
||||
expected = Footer(
|
||||
Div(id=f"{layout._id}_fl"),
|
||||
Div(id=f"{layout._id}_fr"),
|
||||
)
|
||||
|
||||
assert matches(footer, expected)
|
||||
|
||||
def test_header_with_drawer_icons_is_rendered(self, layout):
|
||||
"""Test that header renders with drawer toggle icons.
|
||||
|
||||
Why these elements matter:
|
||||
- 2 Div children: Left/right header structure for organizing controls
|
||||
- Svg: Toggle icon is essential for user interaction with drawer
|
||||
- TestObject(UserProfile): UserProfile component must be present in header
|
||||
- cls="flex gap-1": CSS critical for horizontal alignment of header items
|
||||
- cls="mf-layout-header": Root header class for styling
|
||||
- Only the first div is required to test the presence of the icon
|
||||
- Use TestIcon to test the existence of an icon
|
||||
"""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
header = layout._mk_header()
|
||||
|
||||
header = find_one(layout.render(), Header(cls="mf-layout-header"))
|
||||
|
||||
expected = Header(
|
||||
Div(
|
||||
Div(NotStr(name="panel_right_expand20_regular")),
|
||||
cls="flex gap-1"
|
||||
),
|
||||
Div(
|
||||
TestObject(UserProfile),
|
||||
cls="flex gap-1"
|
||||
),
|
||||
cls="mf-layout-header"
|
||||
Div(
|
||||
TestIcon("panel_right_expand20_regular"),
|
||||
cls="flex gap-1"
|
||||
),
|
||||
cls="mf-layout-header"
|
||||
)
|
||||
|
||||
|
||||
assert matches(header, expected)
|
||||
|
||||
def test_footer_is_rendered(self, root_instance):
|
||||
"""Test that footer renders with correct structure.
|
||||
|
||||
Why these elements matter:
|
||||
- cls Contains "mf-layout-footer": Root footer class for styling
|
||||
- cls Contains "footer": DaisyUI base footer class
|
||||
"""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
footer = layout._mk_footer()
|
||||
|
||||
expected = Footer(
|
||||
cls=Contains("mf-layout-footer")
|
||||
)
|
||||
|
||||
assert matches(footer, expected)
|
||||
|
||||
def test_main_content_is_rendered(self, root_instance):
|
||||
|
||||
def test_main_content_is_rendered_with_some_element(self, layout):
|
||||
"""Test that main content area renders correctly.
|
||||
|
||||
Why these elements matter:
|
||||
- cls="mf-layout-main": Root main class for styling
|
||||
"""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
main = layout._mk_main()
|
||||
|
||||
layout.set_main(Div("Main content"))
|
||||
main = find_one(layout.render(), Main(cls="mf-layout-main"))
|
||||
|
||||
expected = Main(
|
||||
cls="mf-layout-main"
|
||||
Div("Main content"),
|
||||
cls="mf-layout-main"
|
||||
)
|
||||
|
||||
|
||||
assert matches(main, expected)
|
||||
|
||||
def test_left_drawer_is_rendered_when_open(self, root_instance):
|
||||
|
||||
def test_left_drawer_is_rendered_when_open(self, layout):
|
||||
"""Test that left drawer renders with correct classes when open.
|
||||
|
||||
Why these elements matter:
|
||||
- _id: Required for targeting drawer in HTMX updates
|
||||
- _id: Required for targeting drawer in HTMX updates. search by id whenever possible
|
||||
- cls Contains "mf-layout-drawer": Base drawer class for styling
|
||||
- cls Contains "mf-layout-left-drawer": Left-specific drawer positioning
|
||||
- style Contains width: Drawer width must be applied for sizing
|
||||
"""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
drawer = layout._mk_left_drawer()
|
||||
|
||||
layout._state.left_drawer_open = True
|
||||
drawer = find_one(layout.render(), Div(id=f"{layout._id}_ld"))
|
||||
|
||||
expected = Div(
|
||||
_id=f"{layout._id}_ld",
|
||||
cls=Contains("mf-layout-drawer"),
|
||||
#cls=Contains("mf-layout-left-drawer"),
|
||||
style=Contains("width: 250px")
|
||||
_id=f"{layout._id}_ld",
|
||||
cls=Contains("mf-layout-drawer", "mf-layout-left-drawer"),
|
||||
style=Contains("width: 250px")
|
||||
)
|
||||
|
||||
|
||||
assert matches(drawer, expected)
|
||||
|
||||
def test_left_drawer_has_collapsed_class_when_closed(self, root_instance):
|
||||
|
||||
def test_left_drawer_has_collapsed_class_when_closed(self, layout):
|
||||
"""Test that left drawer renders with collapsed class when closed.
|
||||
|
||||
Why these elements matter:
|
||||
@@ -348,19 +347,18 @@ class TestLayoutRender:
|
||||
- cls Contains "collapsed": Class triggers CSS hiding animation
|
||||
- style Contains "width: 0px": Zero width is crucial for collapse animation
|
||||
"""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
layout._state.left_drawer_open = False
|
||||
drawer = layout._mk_left_drawer()
|
||||
|
||||
drawer = find_one(layout.render(), Div(id=f"{layout._id}_ld"))
|
||||
|
||||
expected = Div(
|
||||
_id=f"{layout._id}_ld",
|
||||
cls=Contains("collapsed"),
|
||||
style=Contains("width: 0px")
|
||||
_id=f"{layout._id}_ld",
|
||||
cls=Contains("collapsed"),
|
||||
style=Contains("width: 0px")
|
||||
)
|
||||
|
||||
|
||||
assert matches(drawer, expected)
|
||||
|
||||
def test_right_drawer_is_rendered_when_open(self, root_instance):
|
||||
|
||||
def test_right_drawer_is_rendered_when_open(self, layout):
|
||||
"""Test that right drawer renders with correct classes when open.
|
||||
|
||||
Why these elements matter:
|
||||
@@ -369,19 +367,18 @@ class TestLayoutRender:
|
||||
- cls Contains "mf-layout-right-drawer": Right-specific drawer positioning
|
||||
- style Contains width: Drawer width must be applied for sizing
|
||||
"""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
drawer = layout._mk_right_drawer()
|
||||
|
||||
layout._state.right_drawer_open = True
|
||||
drawer = find_one(layout.render(), Div(id=f"{layout._id}_rd"))
|
||||
|
||||
expected = Div(
|
||||
_id=f"{layout._id}_rd",
|
||||
cls=Contains("mf-layout-drawer"),
|
||||
#cls=Contains("mf-layout-right-drawer"),
|
||||
style=Contains("width: 250px")
|
||||
_id=f"{layout._id}_rd",
|
||||
cls=Contains("mf-layout-drawer", "mf-layout-right-drawer"),
|
||||
style=Contains("width: 250px")
|
||||
)
|
||||
|
||||
|
||||
assert matches(drawer, expected)
|
||||
|
||||
def test_right_drawer_has_collapsed_class_when_closed(self, root_instance):
|
||||
|
||||
def test_right_drawer_has_collapsed_class_when_closed(self, layout):
|
||||
"""Test that right drawer renders with collapsed class when closed.
|
||||
|
||||
Why these elements matter:
|
||||
@@ -389,94 +386,82 @@ class TestLayoutRender:
|
||||
- cls Contains "collapsed": Class triggers CSS hiding animation
|
||||
- style Contains "width: 0px": Zero width is crucial for collapse animation
|
||||
"""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
layout._state.right_drawer_open = False
|
||||
drawer = layout._mk_right_drawer()
|
||||
|
||||
drawer = find_one(layout.render(), Div(id=f"{layout._id}_rd"))
|
||||
|
||||
expected = Div(
|
||||
_id=f"{layout._id}_rd",
|
||||
cls=Contains("collapsed"),
|
||||
style=Contains("width: 0px")
|
||||
_id=f"{layout._id}_rd",
|
||||
cls=Contains("collapsed"),
|
||||
style=Contains("width: 0px")
|
||||
)
|
||||
|
||||
|
||||
assert matches(drawer, expected)
|
||||
|
||||
def test_drawer_width_is_applied_as_style(self, root_instance):
|
||||
|
||||
def test_drawer_width_is_applied_as_style(self, layout):
|
||||
"""Test that custom drawer width is applied as inline style.
|
||||
|
||||
Why this test matters:
|
||||
- style Contains "width: 300px": Verifies that width updates are reflected in style attribute
|
||||
"""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
layout._state.left_drawer_width = 300
|
||||
drawer = layout._mk_left_drawer()
|
||||
|
||||
drawer = find_one(layout.render(), Div(id=f"{layout._id}_ld"))
|
||||
|
||||
expected = Div(
|
||||
style=Contains("width: 300px")
|
||||
style=Contains("width: 300px")
|
||||
)
|
||||
|
||||
|
||||
assert matches(drawer, expected)
|
||||
|
||||
def test_left_drawer_has_resizer_element(self, root_instance):
|
||||
|
||||
def test_left_drawer_has_resizer_element(self, layout):
|
||||
"""Test that left drawer contains resizer element.
|
||||
|
||||
Why this test matters:
|
||||
- Resizer element must be present for drawer width adjustment
|
||||
- cls "mf-resizer-left": Left-specific resizer for correct edge positioning
|
||||
"""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
drawer = layout._mk_left_drawer()
|
||||
|
||||
drawer = find(layout.render(), Div(id=f"{layout._id}_ld"))
|
||||
resizers = find(drawer, Div(cls=Contains("mf-resizer-left")))
|
||||
assert len(resizers) == 1, "Left drawer should contain exactly one resizer element"
|
||||
|
||||
def test_right_drawer_has_resizer_element(self, root_instance):
|
||||
|
||||
def test_right_drawer_has_resizer_element(self, layout):
|
||||
"""Test that right drawer contains resizer element.
|
||||
|
||||
Why this test matters:
|
||||
- Resizer element must be present for drawer width adjustment
|
||||
- cls "mf-resizer-right": Right-specific resizer for correct edge positioning
|
||||
"""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
drawer = layout._mk_right_drawer()
|
||||
|
||||
drawer = find(layout.render(), Div(id=f"{layout._id}_rd"))
|
||||
resizers = find(drawer, Div(cls=Contains("mf-resizer-right")))
|
||||
assert len(resizers) == 1, "Right drawer should contain exactly one resizer element"
|
||||
|
||||
def test_drawer_groups_are_separated_by_dividers(self, root_instance):
|
||||
|
||||
def test_drawer_groups_are_separated_by_dividers(self, layout):
|
||||
"""Test that multiple groups in drawer are separated by divider elements.
|
||||
|
||||
Why this test matters:
|
||||
- Dividers provide visual separation between content groups
|
||||
- At least one divider should exist when multiple groups are present
|
||||
"""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
|
||||
|
||||
layout.left_drawer.add(Div("Item 1"), group="group1")
|
||||
layout.left_drawer.add(Div("Item 2"), group="group2")
|
||||
|
||||
drawer = layout._mk_left_drawer()
|
||||
|
||||
|
||||
drawer = find(layout.render(), Div(id=f"{layout._id}_ld"))
|
||||
content_wrappers = find(drawer, Div(cls="mf-layout-drawer-content"))
|
||||
assert len(content_wrappers) == 1
|
||||
|
||||
|
||||
content = content_wrappers[0]
|
||||
|
||||
|
||||
dividers = find(content, Div(cls="divider"))
|
||||
assert len(dividers) >= 1, "Groups should be separated by dividers"
|
||||
|
||||
def test_resizer_script_is_included(self, root_instance):
|
||||
|
||||
def test_resizer_script_is_included(self, layout):
|
||||
"""Test that resizer initialization script is included in render.
|
||||
|
||||
Why this test matters:
|
||||
- Script element: Required to initialize resizer functionality
|
||||
- Script contains initResizer call: Ensures resizer is activated for this layout instance
|
||||
"""
|
||||
layout = Layout(root_instance, app_name="Test App")
|
||||
rendered = layout.render()
|
||||
|
||||
scripts = find(rendered, Script())
|
||||
assert len(scripts) == 1, "Layout should contain exactly one script element"
|
||||
|
||||
script_content = str(scripts[0].children[0])
|
||||
assert f"initResizer('{layout._id}')" in script_content, "Script must initialize resizer with layout ID"
|
||||
script = find_one(layout.render(), Script())
|
||||
expected = TestScript(f"initResizer('{layout._id}');")
|
||||
|
||||
assert matches(script, expected)
|
||||
|
||||
Reference in New Issue
Block a user