Merge pull request #969 from Textualize/more-testing

More testing
This commit is contained in:
Will McGugan
2022-10-25 14:15:43 +01:00
committed by GitHub
10 changed files with 5075 additions and 73 deletions

View File

@@ -14,5 +14,3 @@ class GridApp(App):
app = GridApp(css_path="grid.css") app = GridApp(css_path="grid.css")
if __name__ == "__main__":
app.run()

View File

@@ -13,6 +13,3 @@ class LinksApp(App):
app = LinksApp(css_path="links.css") app = LinksApp(css_path="links.css")
if __name__ == "__main__":
app.run()

View File

@@ -7,7 +7,9 @@ class CheckboxApp(App):
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
yield Static("[b]Example checkboxes\n", classes="label") yield Static("[b]Example checkboxes\n", classes="label")
yield Horizontal( yield Horizontal(
Static("off: ", classes="label"), Checkbox(), classes="container" Static("off: ", classes="label"),
Checkbox(animate=False),
classes="container",
) )
yield Horizontal( yield Horizontal(
Static("on: ", classes="label"), Static("on: ", classes="label"),

View File

@@ -4,7 +4,16 @@ from textual.widgets import Footer
class FooterApp(App): class FooterApp(App):
BINDINGS = [Binding(key="q", action="quit", description="Quit the app")] BINDINGS = [
Binding(key="q", action="quit", description="Quit the app"),
Binding(
key="question_mark",
action="help",
description="Show help screen",
key_display="?",
),
Binding(key="j", action="down", description="Scroll down", show=False),
]
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
yield Footer() yield Footer()

View File

@@ -11,13 +11,13 @@ The example below populates a table with CSV data.
=== "Output" === "Output"
```{.textual path="docs/examples/widgets/table.py"} ```{.textual path="docs/examples/widgets/data_table.py"}
``` ```
=== "table.py" === "data_table.py"
```python ```python
--8<-- "docs/examples/widgets/table.py" --8<-- "docs/examples/widgets/data_table.py"
``` ```

View File

@@ -605,7 +605,7 @@ class App(Generic[ReturnType], DOMNode):
assert press assert press
driver = app._driver driver = app._driver
assert driver is not None assert driver is not None
await asyncio.sleep(0.01) await asyncio.sleep(0.02)
for key in press: for key in press:
if key == "_": if key == "_":
print("(pause 50ms)") print("(pause 50ms)")
@@ -632,7 +632,13 @@ class App(Generic[ReturnType], DOMNode):
print(f"press {key!r} (char={char!r})") print(f"press {key!r} (char={char!r})")
key_event = events.Key(self, key, char) key_event = events.Key(self, key, char)
driver.send_event(key_event) driver.send_event(key_event)
await asyncio.sleep(0.01) # TODO: A bit of a fudge - extra sleep after tabbing to help guard against race
# condition between widget-level key handling and app/screen level handling.
# More information here: https://github.com/Textualize/textual/issues/1009
# This conditional sleep can be removed after that issue is closed.
if key == "tab":
await asyncio.sleep(0.05)
await asyncio.sleep(0.02)
await app._animator.wait_for_idle() await app._animator.wait_for_idle()

File diff suppressed because one or more lines are too long

View File

@@ -59,6 +59,7 @@ def snap_compare(
""" """
node = request.node node = request.node
app = import_app(app_path) app = import_app(app_path)
compare.app = app
actual_screenshot = take_svg_screenshot( actual_screenshot = take_svg_screenshot(
app=app, app=app,
press=press, press=press,

View File

@@ -1,3 +1,13 @@
from pathlib import Path, PurePosixPath
import pytest
from textual.app import App
from textual.widgets import Input, Button
# --- Layout related stuff ---
def test_grid_layout_basic(snap_compare): def test_grid_layout_basic(snap_compare):
assert snap_compare("docs/examples/guide/layout/grid_layout1.py") assert snap_compare("docs/examples/guide/layout/grid_layout1.py")
@@ -26,7 +36,73 @@ def test_dock_layout_sidebar(snap_compare):
assert snap_compare("docs/examples/guide/layout/dock_layout2_sidebar.py") assert snap_compare("docs/examples/guide/layout/dock_layout2_sidebar.py")
# --- Widgets - rendering and basic interactions ---
# Each widget should have a canonical example that is display in the docs.
# When adding a new widget, ideally we should also create a snapshot test
# from these examples which test rendering and simple interactions with it.
def test_checkboxes(snap_compare): def test_checkboxes(snap_compare):
"""Tests checkboxes but also acts a regression test for using """Tests checkboxes but also acts a regression test for using
width: auto in a Horizontal layout context.""" width: auto in a Horizontal layout context."""
assert snap_compare("docs/examples/widgets/checkbox.py") press = [
"shift+tab",
"enter", # toggle off
"shift+tab",
"wait:20",
"enter", # toggle on
"wait:20",
]
assert snap_compare("docs/examples/widgets/checkbox.py", press=press)
def test_input_and_focus(snap_compare):
press = [
"tab",
*"Darren", # Focus first input, write "Darren"
"tab",
*"Burns", # Tab focus to second input, write "Burns"
]
assert snap_compare("docs/examples/widgets/input.py", press=press)
# Assert that the state of the Input is what we'd expect
app: App = snap_compare.app
input: Input = app.query_one(Input)
assert input.value == "Darren"
assert input.cursor_position == 6
assert input.view_position == 0
def test_buttons_render(snap_compare):
# Testing button rendering. We press tab to focus the first button too.
assert snap_compare("docs/examples/widgets/button.py", press=["tab"])
app = snap_compare.app
button: Button = app.query_one(Button)
assert app.focused is button
def test_datatable_render(snap_compare):
press = ["tab", "down", "down", "right", "up", "left"]
assert snap_compare("docs/examples/widgets/data_table.py", press=press)
def test_footer_render(snap_compare):
assert snap_compare("docs/examples/widgets/footer.py")
def test_header_render(snap_compare):
assert snap_compare("docs/examples/widgets/header.py")
# --- CSS properties ---
# We have a canonical example for each CSS property that is shown in their docs.
# If any of these change, something has likely broken, so snapshot each of them.
PATHS = [
str(PurePosixPath(path)) for path in Path("docs/examples/styles").iterdir() if path.suffix == ".py"
]
@pytest.mark.parametrize("path", PATHS)
def test_css_property_snapshot(path, snap_compare):
assert snap_compare(path)