Files
textual/tests/css/test_screen_css.py
2025-02-19 21:13:18 +00:00

309 lines
8.4 KiB
Python

from textual.app import App
from textual.color import Color
from textual.screen import Screen
from textual.widgets import Label
RED = Color(255, 0, 0)
GREEN = Color(0, 255, 0)
BLUE = Color(0, 0, 255)
class BaseScreen(Screen):
def compose(self):
yield Label("Hello, world!", id="app-css")
yield Label("Hello, world!", id="screen-css-path")
yield Label("Hello, world!", id="screen-css")
class ScreenWithCSS(Screen):
SCOPED_CSS = False
CSS = """
#screen-css {
background: #ff0000;
}
"""
CSS_PATH = "test_screen_css.tcss"
def compose(self):
yield Label("Hello, world!", id="app-css")
yield Label("Hello, world!", id="screen-css-path")
yield Label("Hello, world!", id="screen-css")
class BaseApp(App):
"""Base app for testing screen CSS when pushing screens."""
CSS = """
#app-css {
background: #00ff00;
}
#screen-css-path {
background: #00ff00;
}
#screen-css {
background: #00ff00;
}
"""
def on_mount(self):
self.push_screen(BaseScreen())
class SwitchBaseApp(BaseApp):
"""Base app for testing screen CSS when switching a screen."""
def on_mount(self):
self.push_screen(BaseScreen())
def check_colors_before_screen_css(app: BaseApp):
assert app.screen.query_one("#app-css").styles.background == GREEN
assert app.screen.query_one("#screen-css-path").styles.background == GREEN
assert app.screen.query_one("#screen-css").styles.background == GREEN
def check_colors_after_screen_css(app: BaseApp):
assert app.screen.query_one("#app-css").styles.background == GREEN
assert app.screen.query_one("#screen-css-path").styles.background == BLUE
assert app.screen.query_one("#screen-css").styles.background == RED
async def test_screen_pushing_and_popping_does_not_reparse_css():
"""Check that pushing and popping the same screen doesn't trigger CSS reparses."""
class MyApp(BaseApp):
def key_p(self):
self.push_screen(ScreenWithCSS())
def key_o(self):
self.pop_screen()
counter = 0
def reparse_wrapper(reparse):
def _reparse(*args, **kwargs):
nonlocal counter
counter += 1
return reparse(*args, **kwargs)
return _reparse
app = MyApp()
app.stylesheet.reparse = reparse_wrapper(app.stylesheet.reparse)
async with app.run_test() as pilot:
await pilot.press("p")
await pilot.press("o")
await pilot.press("p")
await pilot.press("o")
await pilot.press("p")
await pilot.press("o")
await pilot.press("p")
await pilot.press("o")
assert counter == 1
async def test_screen_css_push_screen_instance():
"""Check that screen CSS is loaded and applied when pushing a screen instance."""
class MyApp(BaseApp):
def key_p(self):
self.push_screen(ScreenWithCSS())
def key_o(self):
self.pop_screen()
app = MyApp()
async with app.run_test() as pilot:
check_colors_before_screen_css(app)
await pilot.press("p")
check_colors_after_screen_css(app)
await pilot.press("o")
check_colors_after_screen_css(app)
async def test_screen_css_push_screen_instance_by_name():
"""Check that screen CSS is loaded and applied when pushing a screen name that points to a screen instance."""
class MyApp(BaseApp):
SCREENS = {"screenwithcss": ScreenWithCSS}
def key_p(self):
self.push_screen("screenwithcss")
def key_o(self):
self.pop_screen()
app = MyApp()
async with app.run_test() as pilot:
check_colors_before_screen_css(app)
await pilot.press("p")
check_colors_after_screen_css(app)
await pilot.press("o")
check_colors_after_screen_css(app)
async def test_screen_css_push_screen_type_by_name():
"""Check that screen CSS is loaded and applied when pushing a screen name that points to a screen class."""
class MyApp(BaseApp):
SCREENS = {"screenwithcss": ScreenWithCSS}
def key_p(self):
self.push_screen("screenwithcss")
def key_o(self):
self.pop_screen()
app = MyApp()
async with app.run_test() as pilot:
check_colors_before_screen_css(app)
await pilot.press("p")
check_colors_after_screen_css(app)
await pilot.press("o")
check_colors_after_screen_css(app)
async def test_screen_css_switch_screen_instance():
"""Check that screen CSS is loaded and applied when switching to a screen instance."""
class MyApp(SwitchBaseApp):
def key_p(self):
self.switch_screen(ScreenWithCSS())
def key_o(self):
self.pop_screen()
app = MyApp()
async with app.run_test() as pilot:
check_colors_before_screen_css(app)
await pilot.press("p")
check_colors_after_screen_css(app)
await pilot.press("o")
check_colors_after_screen_css(app)
async def test_screen_css_switch_screen_instance_by_name():
"""Check that screen CSS is loaded and applied when switching a screen name that points to a screen instance."""
class MyApp(SwitchBaseApp):
SCREENS = {"screenwithcss": ScreenWithCSS}
def key_p(self):
self.switch_screen("screenwithcss")
def key_o(self):
self.pop_screen()
app = MyApp()
async with app.run_test() as pilot:
check_colors_before_screen_css(app)
await pilot.press("p")
check_colors_after_screen_css(app)
await pilot.press("o")
check_colors_after_screen_css(app)
async def test_screen_css_switch_screen_type_by_name():
"""Check that screen CSS is loaded and applied when switching a screen name that points to a screen class."""
class MyApp(SwitchBaseApp):
SCREENS = {"screenwithcss": ScreenWithCSS}
async def key_p(self):
self.switch_screen("screenwithcss")
def key_o(self):
self.pop_screen()
app = MyApp()
async with app.run_test() as pilot:
check_colors_before_screen_css(app)
await pilot.press("p")
check_colors_after_screen_css(app)
await pilot.press("o")
check_colors_after_screen_css(app)
async def test_screen_css_switch_mode_screen_instance():
"""Check that screen CSS is loaded and applied when switching to a mode with a screen instance."""
class MyApp(BaseApp):
MODES = {
"base": BaseScreen,
"mode": ScreenWithCSS,
}
def key_p(self):
self.switch_mode("mode")
def key_o(self):
self.switch_mode("base")
app = MyApp()
async with app.run_test() as pilot:
await pilot.press("o")
check_colors_before_screen_css(app)
await pilot.press("p")
check_colors_after_screen_css(app)
await pilot.press("o")
check_colors_after_screen_css(app)
async def test_screen_css_switch_mode_screen_instance_by_name():
"""Check that screen CSS is loaded and applied when switching to a mode with a screen instance name."""
class MyApp(BaseApp):
SCREENS = {
"screenwithcss": ScreenWithCSS,
}
MODES = {
"base": BaseScreen,
"mode": "screenwithcss",
}
def key_p(self):
self.switch_mode("mode")
def key_o(self):
self.switch_mode("base")
app = MyApp()
async with app.run_test() as pilot:
await pilot.press("o")
check_colors_before_screen_css(app)
await pilot.press("p")
check_colors_after_screen_css(app)
await pilot.press("o")
check_colors_after_screen_css(app)
async def test_screen_css_switch_mode_screen_type_by_name():
"""Check that screen CSS is loaded and applied when switching to a mode with a screen type name."""
class MyApp(BaseApp):
SCREENS = {
"screenwithcss": ScreenWithCSS,
}
MODES = {
"base": BaseScreen,
"mode": "screenwithcss",
}
def key_p(self):
self.switch_mode("mode")
def key_o(self):
self.switch_mode("base")
app = MyApp()
async with app.run_test() as pilot:
await pilot.press("o")
check_colors_before_screen_css(app)
await pilot.press("p")
check_colors_after_screen_css(app)
await pilot.press("o")
check_colors_after_screen_css(app)