From b592ac077ab3bd4d9e4b5dade314c0cfc4cc9f19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 16 May 2023 11:27:24 +0100 Subject: [PATCH 1/6] AUTO_FOCUS targets first focusable widget. Related issues: #2578. --- CHANGELOG.md | 1 + src/textual/screen.py | 7 +++++-- tests/test_screens.py | 21 ++++++++++++++++++--- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5991f818d..216339e66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fixed `TreeNode.toggle` and `TreeNode.toggle_all` not posting a `Tree.NodeExpanded` or `Tree.NodeCollapsed` message https://github.com/Textualize/textual/issues/2535 - `footer--description` component class was being ignored https://github.com/Textualize/textual/issues/2544 - Pasting empty selection in `Input` would raise an exception https://github.com/Textualize/textual/issues/2563 +- `Screen.AUTO_FOCUS` now focuses the first _focusable_ widget that matches the selector https://github.com/Textualize/textual/issues/2578 ### Added diff --git a/src/textual/screen.py b/src/textual/screen.py index af0b006be..9f065dfbf 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -668,11 +668,14 @@ class Screen(Generic[ScreenResultType], Widget): size = self.app.size if self.AUTO_FOCUS is not None and self.focused is None: try: - to_focus = self.query(self.AUTO_FOCUS).first() + focus_candidates = self.query(self.AUTO_FOCUS) except NoMatches: pass else: - self.set_focus(to_focus) + for widget in focus_candidates: + if widget.focusable: + self.set_focus(widget) + break self._refresh_layout(size, full=True) self.refresh() diff --git a/tests/test_screens.py b/tests/test_screens.py index 2e3dbfcbe..7ddc8b20e 100644 --- a/tests/test_screens.py +++ b/tests/test_screens.py @@ -6,7 +6,7 @@ import pytest from textual.app import App, ScreenStackError from textual.screen import Screen -from textual.widgets import Button, Input +from textual.widgets import Button, Input, Label skip_py310 = pytest.mark.skipif( sys.version_info.minor == 10 and sys.version_info.major == 3, @@ -155,8 +155,7 @@ async def test_screens(): async def test_auto_focus(): class MyScreen(Screen[None]): - def compose(self) -> None: - print("composing") + def compose(self): yield Button() yield Input(id="one") yield Input(id="two") @@ -192,3 +191,19 @@ async def test_auto_focus(): assert app.focused is None app.pop_screen() assert app.focused.id == "two" + + +async def test_auto_focus_skips_non_focusable_widgets(): + class MyScreen(Screen[None]): + def compose(self): + yield Label() + yield Button() + + class MyApp(App[None]): + def on_mount(self): + self.push_screen(MyScreen()) + + app = MyApp() + async with app.run_test(): + assert app.focused is not None + assert isinstance(app.focused, Button) From a6ee867ee36506c65d3cc14041e0f79b66ac9cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Tue, 16 May 2023 11:39:38 +0100 Subject: [PATCH 2/6] Fix tests. --- src/textual/screen.py | 4 ++-- tests/snapshot_tests/test_snapshots.py | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/textual/screen.py b/src/textual/screen.py index 9f065dfbf..5cec44b88 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -666,6 +666,8 @@ class Screen(Generic[ScreenResultType], Widget): """Screen has resumed.""" self.stack_updates += 1 size = self.app.size + self._refresh_layout(size, full=True) + self.refresh() if self.AUTO_FOCUS is not None and self.focused is None: try: focus_candidates = self.query(self.AUTO_FOCUS) @@ -676,8 +678,6 @@ class Screen(Generic[ScreenResultType], Widget): if widget.focusable: self.set_focus(widget) break - self._refresh_layout(size, full=True) - self.refresh() def _on_screen_suspend(self) -> None: """Screen has suspended.""" diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py index ea5e32153..d70fc761e 100644 --- a/tests/snapshot_tests/test_snapshots.py +++ b/tests/snapshot_tests/test_snapshots.py @@ -203,9 +203,11 @@ def test_option_list(snap_compare): assert snap_compare(WIDGET_EXAMPLES_DIR / "option_list_options.py") assert snap_compare(WIDGET_EXAMPLES_DIR / "option_list_tables.py") + def test_option_list_build(snap_compare): assert snap_compare(SNAPSHOT_APPS_DIR / "option_list.py") + def test_progress_bar_indeterminate(snap_compare): assert snap_compare(WIDGET_EXAMPLES_DIR / "progress_bar_isolated_.py", press=["f"]) @@ -440,7 +442,7 @@ def test_modal_dialog_bindings_input(snap_compare): # Check https://github.com/Textualize/textual/issues/2194 assert snap_compare( SNAPSHOT_APPS_DIR / "modal_screen_bindings.py", - press=["enter", "tab", "h", "!", "left", "i", "tab"], + press=["enter", "h", "!", "left", "i", "tab"], ) From 765c7ce037cf2a54f88f9813b1aa0501f91c6f19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 17 May 2023 10:01:01 +0100 Subject: [PATCH 3/6] Simplify auto focus code. Related comments: https://github.com/Textualize/textual/pull/2581\#discussion_r1195595104. --- src/textual/screen.py | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/textual/screen.py b/src/textual/screen.py index 8528aeecc..3cb9b65f2 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -669,15 +669,10 @@ class Screen(Generic[ScreenResultType], Widget): self._refresh_layout(size, full=True) self.refresh() if self.AUTO_FOCUS is not None and self.focused is None: - try: - focus_candidates = self.query(self.AUTO_FOCUS) - except NoMatches: - pass - else: - for widget in focus_candidates: - if widget.focusable: - self.set_focus(widget) - break + for widget in self.query(self.AUTO_FOCUS): + if widget.focusable: + self.set_focus(widget) + break def _on_screen_suspend(self) -> None: """Screen has suspended.""" From 8399a31a461e102b951506493c444c2c28406b7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 17 May 2023 10:09:52 +0100 Subject: [PATCH 4/6] Post ScreenResume to default screen. When the default screen is first created it was not getting the event ScreenResume. All other screens receive a ScreenResume when first created and _all_ screens (the default one and custom screens) receive this event when they become the active screen again, so this was kind of an edge case that needed the event to be posted by hand. Related comments: https://github.com/Textualize/textual/pull/2581\#issuecomment-1550231559 --- src/textual/app.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/textual/app.py b/src/textual/app.py index c1376cd22..75703d8f7 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -2133,6 +2133,7 @@ class App(Generic[ReturnType], DOMNode): screen = Screen(id="_default") self._register(self, screen) self._screen_stack.append(screen) + screen.post_message(events.ScreenResume()) await super().on_event(event) elif isinstance(event, events.InputEvent) and not event.is_forwarded: From 45686c8acaed9263fb31b364381a311c8681de16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 17 May 2023 10:17:20 +0100 Subject: [PATCH 5/6] Fix tests. --- .../__snapshots__/test_snapshots.ambr | 1808 +++++++++-------- tests/snapshot_tests/test_snapshots.py | 14 +- tests/test_app.py | 3 +- tests/test_on.py | 2 +- tests/test_paste.py | 1 + tests/toggles/test_radioset.py | 7 +- 6 files changed, 917 insertions(+), 918 deletions(-) diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr index 8b03449d9..0bc5ae9fd 100644 --- a/tests/snapshot_tests/__snapshots__/test_snapshots.ambr +++ b/tests/snapshot_tests/__snapshots__/test_snapshots.ambr @@ -21,138 +21,138 @@ font-weight: 700; } - .terminal-1593336641-matrix { + .terminal-644510384-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1593336641-title { + .terminal-644510384-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1593336641-r1 { fill: #c5c8c6 } - .terminal-1593336641-r2 { fill: #7ae998 } - .terminal-1593336641-r3 { fill: #0a180e;font-weight: bold } - .terminal-1593336641-r4 { fill: #008139 } - .terminal-1593336641-r5 { fill: #e3dbce } - .terminal-1593336641-r6 { fill: #e1e1e1 } - .terminal-1593336641-r7 { fill: #e76580 } - .terminal-1593336641-r8 { fill: #f5e5e9;font-weight: bold } - .terminal-1593336641-r9 { fill: #780028 } + .terminal-644510384-r1 { fill: #c5c8c6 } + .terminal-644510384-r2 { fill: #7ae998 } + .terminal-644510384-r3 { fill: #4ebf71;font-weight: bold } + .terminal-644510384-r4 { fill: #008139 } + .terminal-644510384-r5 { fill: #e3dbce } + .terminal-644510384-r6 { fill: #e1e1e1 } + .terminal-644510384-r7 { fill: #e76580 } + .terminal-644510384-r8 { fill: #f5e5e9;font-weight: bold } + .terminal-644510384-r9 { fill: #780028 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - AlignContainersApp + AlignContainersApp - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - center - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - middle - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + center + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + middle + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + @@ -1739,139 +1739,140 @@ font-weight: 700; } - .terminal-2222688117-matrix { + .terminal-78223076-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2222688117-title { + .terminal-78223076-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2222688117-r1 { fill: #c5c8c6 } - .terminal-2222688117-r2 { fill: #e1e1e1 } - .terminal-2222688117-r3 { fill: #454a50 } - .terminal-2222688117-r4 { fill: #e2e3e3;font-weight: bold } - .terminal-2222688117-r5 { fill: #000000 } - .terminal-2222688117-r6 { fill: #004578 } - .terminal-2222688117-r7 { fill: #dde6ed;font-weight: bold } - .terminal-2222688117-r8 { fill: #dde6ed } - .terminal-2222688117-r9 { fill: #211505 } - .terminal-2222688117-r10 { fill: #e2e3e3 } + .terminal-78223076-r1 { fill: #c5c8c6 } + .terminal-78223076-r2 { fill: #e1e1e1 } + .terminal-78223076-r3 { fill: #454a50 } + .terminal-78223076-r4 { fill: #24292f;font-weight: bold } + .terminal-78223076-r5 { fill: #e2e3e3;font-weight: bold } + .terminal-78223076-r6 { fill: #000000 } + .terminal-78223076-r7 { fill: #004578 } + .terminal-78223076-r8 { fill: #dde6ed;font-weight: bold } + .terminal-78223076-r9 { fill: #dde6ed } + .terminal-78223076-r10 { fill: #211505 } + .terminal-78223076-r11 { fill: #e2e3e3 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - ContentSwitcherApp + ContentSwitcherApp - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - DataTableMarkdown - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ──────────────────────────────────────────────────────────────────── -  Book                                 Year  -  Dune                                 1965  -  Dune Messiah                         1969  -  Children of Dune                     1976  -  God Emperor of Dune                  1981  -  Heretics of Dune                     1984  -  Chapterhouse: Dune                   1985  - - - - - - - - - - - ──────────────────────────────────────────────────────────────────── + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + DataTableMarkdown + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ──────────────────────────────────────────────────────────────────── +  Book                                 Year  +  Dune                                 1965  +  Dune Messiah                         1969  +  Children of Dune                     1976  +  God Emperor of Dune                  1981  +  Heretics of Dune                     1984  +  Chapterhouse: Dune                   1985  + + + + + + + + + + + ──────────────────────────────────────────────────────────────────── @@ -13760,161 +13761,162 @@ font-weight: 700; } - .terminal-65653754-matrix { + .terminal-1022810985-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-65653754-title { + .terminal-1022810985-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-65653754-r1 { fill: #454a50 } - .terminal-65653754-r2 { fill: #507bb3 } - .terminal-65653754-r3 { fill: #7ae998 } - .terminal-65653754-r4 { fill: #ffcf56 } - .terminal-65653754-r5 { fill: #e76580 } - .terminal-65653754-r6 { fill: #c5c8c6 } - .terminal-65653754-r7 { fill: #e2e3e3;font-weight: bold } - .terminal-65653754-r8 { fill: #dde6ed;font-weight: bold } - .terminal-65653754-r9 { fill: #0a180e;font-weight: bold } - .terminal-65653754-r10 { fill: #211505;font-weight: bold } - .terminal-65653754-r11 { fill: #f5e5e9;font-weight: bold } - .terminal-65653754-r12 { fill: #000000 } - .terminal-65653754-r13 { fill: #001541 } - .terminal-65653754-r14 { fill: #008139 } - .terminal-65653754-r15 { fill: #b86b00 } - .terminal-65653754-r16 { fill: #780028 } - .terminal-65653754-r17 { fill: #35383c } - .terminal-65653754-r18 { fill: #3c5577 } - .terminal-65653754-r19 { fill: #559767 } - .terminal-65653754-r20 { fill: #a5883f } - .terminal-65653754-r21 { fill: #964858 } - .terminal-65653754-r22 { fill: #7c7d7e;font-weight: bold } - .terminal-65653754-r23 { fill: #75828b;font-weight: bold } - .terminal-65653754-r24 { fill: #192e1f;font-weight: bold } - .terminal-65653754-r25 { fill: #3a2a13;font-weight: bold } - .terminal-65653754-r26 { fill: #978186;font-weight: bold } - .terminal-65653754-r27 { fill: #0c0c0c } - .terminal-65653754-r28 { fill: #0c1833 } - .terminal-65653754-r29 { fill: #0c592e } - .terminal-65653754-r30 { fill: #7a4c0c } - .terminal-65653754-r31 { fill: #540c24 } + .terminal-1022810985-r1 { fill: #454a50 } + .terminal-1022810985-r2 { fill: #507bb3 } + .terminal-1022810985-r3 { fill: #7ae998 } + .terminal-1022810985-r4 { fill: #ffcf56 } + .terminal-1022810985-r5 { fill: #e76580 } + .terminal-1022810985-r6 { fill: #c5c8c6 } + .terminal-1022810985-r7 { fill: #24292f;font-weight: bold } + .terminal-1022810985-r8 { fill: #dde6ed;font-weight: bold } + .terminal-1022810985-r9 { fill: #0a180e;font-weight: bold } + .terminal-1022810985-r10 { fill: #211505;font-weight: bold } + .terminal-1022810985-r11 { fill: #f5e5e9;font-weight: bold } + .terminal-1022810985-r12 { fill: #000000 } + .terminal-1022810985-r13 { fill: #001541 } + .terminal-1022810985-r14 { fill: #008139 } + .terminal-1022810985-r15 { fill: #b86b00 } + .terminal-1022810985-r16 { fill: #780028 } + .terminal-1022810985-r17 { fill: #35383c } + .terminal-1022810985-r18 { fill: #3c5577 } + .terminal-1022810985-r19 { fill: #559767 } + .terminal-1022810985-r20 { fill: #a5883f } + .terminal-1022810985-r21 { fill: #964858 } + .terminal-1022810985-r22 { fill: #7c7d7e;font-weight: bold } + .terminal-1022810985-r23 { fill: #75828b;font-weight: bold } + .terminal-1022810985-r24 { fill: #192e1f;font-weight: bold } + .terminal-1022810985-r25 { fill: #3a2a13;font-weight: bold } + .terminal-1022810985-r26 { fill: #978186;font-weight: bold } + .terminal-1022810985-r27 { fill: #0c0c0c } + .terminal-1022810985-r28 { fill: #0c1833 } + .terminal-1022810985-r29 { fill: #0c592e } + .terminal-1022810985-r30 { fill: #7a4c0c } + .terminal-1022810985-r31 { fill: #540c24 } + .terminal-1022810985-r32 { fill: #e2e3e3;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - WidgetDisableTestApp + WidgetDisableTestApp - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ButtonButtonButtonButtonButton - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ButtonButtonButtonButtonButton - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ButtonButtonButtonButtonButton - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ButtonButtonButtonButtonButton - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ButtonButtonButtonButtonButton - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ButtonButtonButtonButtonButton - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ButtonButtonButtonButtonButton - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ButtonButtonButtonButtonButton - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ButtonButtonButtonButtonButton + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ButtonButtonButtonButtonButton + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ButtonButtonButtonButtonButton + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ButtonButtonButtonButtonButton + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ButtonButtonButtonButtonButton + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ButtonButtonButtonButtonButton + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ButtonButtonButtonButtonButton + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ButtonButtonButtonButtonButton + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ @@ -14265,147 +14267,148 @@ font-weight: 700; } - .terminal-2863933047-matrix { + .terminal-432027110-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2863933047-title { + .terminal-432027110-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2863933047-r1 { fill: #454a50 } - .terminal-2863933047-r2 { fill: #e1e1e1 } - .terminal-2863933047-r3 { fill: #c5c8c6 } - .terminal-2863933047-r4 { fill: #e2e3e3;font-weight: bold } - .terminal-2863933047-r5 { fill: #262626 } - .terminal-2863933047-r6 { fill: #000000 } - .terminal-2863933047-r7 { fill: #e2e2e2 } - .terminal-2863933047-r8 { fill: #e3e3e3 } - .terminal-2863933047-r9 { fill: #14191f } - .terminal-2863933047-r10 { fill: #b93c5b } - .terminal-2863933047-r11 { fill: #121212 } - .terminal-2863933047-r12 { fill: #1e1e1e } - .terminal-2863933047-r13 { fill: #fea62b } - .terminal-2863933047-r14 { fill: #211505;font-weight: bold } - .terminal-2863933047-r15 { fill: #211505 } - .terminal-2863933047-r16 { fill: #dde8f3;font-weight: bold } - .terminal-2863933047-r17 { fill: #ddedf9 } + .terminal-432027110-r1 { fill: #454a50 } + .terminal-432027110-r2 { fill: #e1e1e1 } + .terminal-432027110-r3 { fill: #c5c8c6 } + .terminal-432027110-r4 { fill: #24292f;font-weight: bold } + .terminal-432027110-r5 { fill: #262626 } + .terminal-432027110-r6 { fill: #000000 } + .terminal-432027110-r7 { fill: #e2e2e2 } + .terminal-432027110-r8 { fill: #e3e3e3 } + .terminal-432027110-r9 { fill: #e2e3e3;font-weight: bold } + .terminal-432027110-r10 { fill: #14191f } + .terminal-432027110-r11 { fill: #b93c5b } + .terminal-432027110-r12 { fill: #121212 } + .terminal-432027110-r13 { fill: #1e1e1e } + .terminal-432027110-r14 { fill: #fea62b } + .terminal-432027110-r15 { fill: #211505;font-weight: bold } + .terminal-432027110-r16 { fill: #211505 } + .terminal-432027110-r17 { fill: #dde8f3;font-weight: bold } + .terminal-432027110-r18 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - EasingApp + EasingApp - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - round▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Animation Duration:1.0 - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - out_sine - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - out_quint - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Welcome to Textual! - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - out_quartI must not fear. - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Fear is the  - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mind-killer. - out_quadFear is the  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁little-death that  - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔brings total  - out_expoobliteration. - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁I will face my fear. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔I will permit it to  - out_elasticpass over me and  - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁through me. - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔And when it has gone  - out_cubic - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ CTRL+P  Focus: Duration Input  CTRL+B  Toggle Dark  + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + round▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Animation Duration:1.0 + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + out_sine + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + out_quint + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Welcome to Textual! + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + out_quartI must not fear. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁Fear is the  + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔mind-killer. + out_quadFear is the  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁little-death that  + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔brings total  + out_expoobliteration. + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁I will face my fear. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔I will permit it to  + out_elasticpass over me and  + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁through me. + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔And when it has gone  + out_cubic + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ CTRL+P  Focus: Duration Input  CTRL+B  Toggle Dark  @@ -16482,146 +16485,146 @@ font-weight: 700; } - .terminal-2572323619-matrix { + .terminal-4085160594-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2572323619-title { + .terminal-4085160594-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2572323619-r1 { fill: #c5c8c6 } - .terminal-2572323619-r2 { fill: #e3e3e3 } - .terminal-2572323619-r3 { fill: #e1e1e1 } - .terminal-2572323619-r4 { fill: #e1e1e1;text-decoration: underline; } - .terminal-2572323619-r5 { fill: #e1e1e1;font-weight: bold } - .terminal-2572323619-r6 { fill: #e1e1e1;font-style: italic; } - .terminal-2572323619-r7 { fill: #98729f;font-weight: bold } - .terminal-2572323619-r8 { fill: #d0b344 } - .terminal-2572323619-r9 { fill: #98a84b } - .terminal-2572323619-r10 { fill: #00823d;font-style: italic; } - .terminal-2572323619-r11 { fill: #ffcf56 } - .terminal-2572323619-r12 { fill: #e76580 } - .terminal-2572323619-r13 { fill: #211505;font-weight: bold } - .terminal-2572323619-r14 { fill: #f5e5e9;font-weight: bold } - .terminal-2572323619-r15 { fill: #b86b00 } - .terminal-2572323619-r16 { fill: #780028 } + .terminal-4085160594-r1 { fill: #c5c8c6 } + .terminal-4085160594-r2 { fill: #e3e3e3 } + .terminal-4085160594-r3 { fill: #e1e1e1 } + .terminal-4085160594-r4 { fill: #e1e1e1;text-decoration: underline; } + .terminal-4085160594-r5 { fill: #e1e1e1;font-weight: bold } + .terminal-4085160594-r6 { fill: #e1e1e1;font-style: italic; } + .terminal-4085160594-r7 { fill: #98729f;font-weight: bold } + .terminal-4085160594-r8 { fill: #d0b344 } + .terminal-4085160594-r9 { fill: #98a84b } + .terminal-4085160594-r10 { fill: #00823d;font-style: italic; } + .terminal-4085160594-r11 { fill: #ffcf56 } + .terminal-4085160594-r12 { fill: #e76580 } + .terminal-4085160594-r13 { fill: #fea62b;font-weight: bold } + .terminal-4085160594-r14 { fill: #f5e5e9;font-weight: bold } + .terminal-4085160594-r15 { fill: #b86b00 } + .terminal-4085160594-r16 { fill: #780028 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - Textual Keys + Textual Keys - - - - Textual Keys - ╭────────────────────────────────────────────────────────────────────────────╮ - Press some keys! - - To quit the app press ctrl+ctwice or press the Quit button below. - ╰────────────────────────────────────────────────────────────────────────────╯ - Key(key='a'character='a'name='a'is_printable=True) - Key(key='b'character='b'name='b'is_printable=True) - - - - - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - ClearQuit - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + Textual Keys + ╭────────────────────────────────────────────────────────────────────────────╮ + Press some keys! + + To quit the app press ctrl+ctwice or press the Quit button below. + ╰────────────────────────────────────────────────────────────────────────────╯ + Key(key='a'character='a'name='a'is_printable=True) + Key(key='b'character='b'name='b'is_printable=True) + + + + + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + ClearQuit + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ @@ -17125,143 +17128,144 @@ font-weight: 700; } - .terminal-4197777529-matrix { + .terminal-4055437288-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-4197777529-title { + .terminal-4055437288-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-4197777529-r1 { fill: #7ae998 } - .terminal-4197777529-r2 { fill: #e76580 } - .terminal-4197777529-r3 { fill: #1e1e1e } - .terminal-4197777529-r4 { fill: #121212 } - .terminal-4197777529-r5 { fill: #c5c8c6 } - .terminal-4197777529-r6 { fill: #0a180e;font-weight: bold } - .terminal-4197777529-r7 { fill: #f5e5e9;font-weight: bold } - .terminal-4197777529-r8 { fill: #e2e2e2 } - .terminal-4197777529-r9 { fill: #008139 } - .terminal-4197777529-r10 { fill: #780028 } - .terminal-4197777529-r11 { fill: #e1e1e1 } - .terminal-4197777529-r12 { fill: #23568b } - .terminal-4197777529-r13 { fill: #14191f } + .terminal-4055437288-r1 { fill: #7ae998 } + .terminal-4055437288-r2 { fill: #e76580 } + .terminal-4055437288-r3 { fill: #1e1e1e } + .terminal-4055437288-r4 { fill: #121212 } + .terminal-4055437288-r5 { fill: #c5c8c6 } + .terminal-4055437288-r6 { fill: #4ebf71;font-weight: bold } + .terminal-4055437288-r7 { fill: #f5e5e9;font-weight: bold } + .terminal-4055437288-r8 { fill: #e2e2e2 } + .terminal-4055437288-r9 { fill: #0a180e;font-weight: bold } + .terminal-4055437288-r10 { fill: #008139 } + .terminal-4055437288-r11 { fill: #780028 } + .terminal-4055437288-r12 { fill: #e1e1e1 } + .terminal-4055437288-r13 { fill: #23568b } + .terminal-4055437288-r14 { fill: #14191f } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - MyApp + MyApp - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - AcceptDeclineAcceptDecline - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - AcceptAccept - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - DeclineDecline - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▆▆ - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - 00 - - 10000001000000 + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + AcceptDeclineAcceptDecline + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + AcceptAccept + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + DeclineDecline + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▆▆ + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + 00 + + 10000001000000 @@ -18731,136 +18735,136 @@ font-weight: 700; } - .terminal-1812315577-matrix { + .terminal-4119903855-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1812315577-title { + .terminal-4119903855-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1812315577-r1 { fill: #c5c8c6 } - .terminal-1812315577-r2 { fill: #e3e3e3 } - .terminal-1812315577-r3 { fill: #e1e1e1 } - .terminal-1812315577-r4 { fill: #004578 } - .terminal-1812315577-r5 { fill: #e0e8ee;font-weight: bold } - .terminal-1812315577-r6 { fill: #e2e3e3 } - .terminal-1812315577-r7 { fill: #ddedf9 } + .terminal-4119903855-r1 { fill: #c5c8c6 } + .terminal-4119903855-r2 { fill: #e3e3e3 } + .terminal-4119903855-r3 { fill: #e1e1e1 } + .terminal-4119903855-r4 { fill: #004578 } + .terminal-4119903855-r5 { fill: #ddedf9;font-weight: bold } + .terminal-4119903855-r6 { fill: #e2e3e3 } + .terminal-4119903855-r7 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - OptionListApp + OptionListApp - - - - OptionListApp - - - - ────────────────────────────────────────────────────── - Aerilon - Aquaria - Canceron - Caprica - Gemenon - Leonis - Libran - Picon - Sagittaron - Scorpia - Tauron - Virgon - - - ────────────────────────────────────────────────────── - - - + + + + OptionListApp + + + + ────────────────────────────────────────────────────── + Aerilon + Aquaria + Canceron + Caprica + Gemenon + Leonis + Libran + Picon + Sagittaron + Scorpia + Tauron + Virgon + + + ────────────────────────────────────────────────────── + + + @@ -18891,139 +18895,139 @@ font-weight: 700; } - .terminal-1041266590-matrix { + .terminal-3443619924-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1041266590-title { + .terminal-3443619924-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1041266590-r1 { fill: #c5c8c6 } - .terminal-1041266590-r2 { fill: #e3e3e3 } - .terminal-1041266590-r3 { fill: #e1e1e1 } - .terminal-1041266590-r4 { fill: #004578 } - .terminal-1041266590-r5 { fill: #e0e8ee;font-weight: bold } - .terminal-1041266590-r6 { fill: #e2e3e3 } - .terminal-1041266590-r7 { fill: #42464b } - .terminal-1041266590-r8 { fill: #777a7e } - .terminal-1041266590-r9 { fill: #14191f } - .terminal-1041266590-r10 { fill: #ddedf9 } + .terminal-3443619924-r1 { fill: #c5c8c6 } + .terminal-3443619924-r2 { fill: #e3e3e3 } + .terminal-3443619924-r3 { fill: #e1e1e1 } + .terminal-3443619924-r4 { fill: #004578 } + .terminal-3443619924-r5 { fill: #ddedf9;font-weight: bold } + .terminal-3443619924-r6 { fill: #e2e3e3 } + .terminal-3443619924-r7 { fill: #42464b } + .terminal-3443619924-r8 { fill: #777a7e } + .terminal-3443619924-r9 { fill: #14191f } + .terminal-3443619924-r10 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - OptionListApp + OptionListApp - - - - OptionListApp - - - - ────────────────────────────────────────────────────── - Aerilon - Aquaria - ──────────────────────────────────────────────────── - Canceron - Caprica - ──────────────────────────────────────────────────── - Gemenon - ──────────────────────────────────────────────────── - Leonis - Libran - ────────────────────────────────────────────────────▅▅ - Picon - ──────────────────────────────────────────────────── - Sagittaron - ────────────────────────────────────────────────────── - - - + + + + OptionListApp + + + + ────────────────────────────────────────────────────── + Aerilon + Aquaria + ──────────────────────────────────────────────────── + Canceron + Caprica + ──────────────────────────────────────────────────── + Gemenon + ──────────────────────────────────────────────────── + Leonis + Libran + ────────────────────────────────────────────────────▅▅ + Picon + ──────────────────────────────────────────────────── + Sagittaron + ────────────────────────────────────────────────────── + + + @@ -19054,140 +19058,140 @@ font-weight: 700; } - .terminal-1620527509-matrix { + .terminal-589190207-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1620527509-title { + .terminal-589190207-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1620527509-r1 { fill: #c5c8c6 } - .terminal-1620527509-r2 { fill: #e3e3e3 } - .terminal-1620527509-r3 { fill: #e1e1e1 } - .terminal-1620527509-r4 { fill: #004578 } - .terminal-1620527509-r5 { fill: #e0e8ee;font-weight: bold;font-style: italic; } - .terminal-1620527509-r6 { fill: #e2e3e3 } - .terminal-1620527509-r7 { fill: #e0e8ee;font-weight: bold } - .terminal-1620527509-r8 { fill: #14191f } - .terminal-1620527509-r9 { fill: #e2e3e3;font-style: italic; } - .terminal-1620527509-r10 { fill: #e2e3e3;font-weight: bold } - .terminal-1620527509-r11 { fill: #ddedf9 } + .terminal-589190207-r1 { fill: #c5c8c6 } + .terminal-589190207-r2 { fill: #e3e3e3 } + .terminal-589190207-r3 { fill: #e1e1e1 } + .terminal-589190207-r4 { fill: #004578 } + .terminal-589190207-r5 { fill: #ddedf9;font-weight: bold;font-style: italic; } + .terminal-589190207-r6 { fill: #e2e3e3 } + .terminal-589190207-r7 { fill: #ddedf9;font-weight: bold } + .terminal-589190207-r8 { fill: #14191f } + .terminal-589190207-r9 { fill: #e2e3e3;font-style: italic; } + .terminal-589190207-r10 { fill: #e2e3e3;font-weight: bold } + .terminal-589190207-r11 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - OptionListApp + OptionListApp - - - - OptionListApp - - - - ────────────────────────────────────────────────────── -                   Data for Aerilon                   - ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ - Patron God   Population    Capital City   ▂▂ - ┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩ - Demeter      1.2 Billion   Gaoth           - └───────────────┴────────────────┴─────────────────┘ -                   Data for Aquaria                   - ┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ - Patron God    Population   Capital City    - ┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩ - Hermes        75,000       None            - └────────────────┴───────────────┴─────────────────┘ -                  Data for Canceron                   - ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ - ────────────────────────────────────────────────────── - - - + + + + OptionListApp + + + + ────────────────────────────────────────────────────── +                   Data for Aerilon                   + ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ + Patron God   Population    Capital City   ▂▂ + ┡━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩ + Demeter      1.2 Billion   Gaoth           + └───────────────┴────────────────┴─────────────────┘ +                   Data for Aquaria                   + ┏━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ + Patron God    Population   Capital City    + ┡━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩ + Hermes        75,000       None            + └────────────────┴───────────────┴─────────────────┘ +                  Data for Canceron                   + ┏━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ + ────────────────────────────────────────────────────── + + + @@ -19218,134 +19222,135 @@ font-weight: 700; } - .terminal-2380819869-matrix { + .terminal-1891986877-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-2380819869-title { + .terminal-1891986877-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-2380819869-r1 { fill: #e1e9ef;font-weight: bold } - .terminal-2380819869-r2 { fill: #c5c8c6 } - .terminal-2380819869-r3 { fill: #e4e5e6 } - .terminal-2380819869-r4 { fill: #4f5459 } - .terminal-2380819869-r5 { fill: #cc555a } + .terminal-1891986877-r1 { fill: #ddedf9;font-weight: bold } + .terminal-1891986877-r2 { fill: #e1e9ef;font-weight: bold } + .terminal-1891986877-r3 { fill: #c5c8c6 } + .terminal-1891986877-r4 { fill: #e4e5e6 } + .terminal-1891986877-r5 { fill: #4f5459 } + .terminal-1891986877-r6 { fill: #cc555a } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - OptionListApp + OptionListApp - - - - OneOneOne - TwoTwoTwo - ──────────────────────────────────────────────────────────────────────────────── - ThreeThreeThree - - - - - - - - - - - - - - - - - - - + + + + OneOneOne + TwoTwoTwo + ──────────────────────────────────────────────────────────────────────────────── + ThreeThreeThree + + + + + + + + + + + + + + + + + + + @@ -20973,135 +20978,135 @@ font-weight: 700; } - .terminal-1586716314-matrix { + .terminal-1484676870-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1586716314-title { + .terminal-1484676870-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1586716314-r1 { fill: #c5c8c6 } - .terminal-1586716314-r2 { fill: #737373 } - .terminal-1586716314-r3 { fill: #e1e1e1;font-weight: bold } - .terminal-1586716314-r4 { fill: #323232 } - .terminal-1586716314-r5 { fill: #0178d4 } - .terminal-1586716314-r6 { fill: #e1e1e1 } + .terminal-1484676870-r1 { fill: #c5c8c6 } + .terminal-1484676870-r2 { fill: #737373 } + .terminal-1484676870-r3 { fill: #e1e1e1;font-weight: bold } + .terminal-1484676870-r4 { fill: #474747 } + .terminal-1484676870-r5 { fill: #0178d4 } + .terminal-1484676870-r6 { fill: #e1e1e1 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - QuicklyChangeTabsApp + QuicklyChangeTabsApp - + - - - onetwothree - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - three - - - - - - - - - - - - - - - - - - + + + onetwothree + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + three + + + + + + + + + + + + + + + + + + @@ -22245,136 +22250,136 @@ font-weight: 700; } - .terminal-1422407852-matrix { + .terminal-1161182100-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1422407852-title { + .terminal-1161182100-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1422407852-r1 { fill: #c5c8c6 } - .terminal-1422407852-r2 { fill: #e3e3e3 } - .terminal-1422407852-r3 { fill: #e1e1e1 } - .terminal-1422407852-r4 { fill: #1e1e1e } - .terminal-1422407852-r5 { fill: #121212 } - .terminal-1422407852-r6 { fill: #787878 } - .terminal-1422407852-r7 { fill: #a8a8a8 } + .terminal-1161182100-r1 { fill: #c5c8c6 } + .terminal-1161182100-r2 { fill: #e3e3e3 } + .terminal-1161182100-r3 { fill: #e1e1e1 } + .terminal-1161182100-r4 { fill: #1e1e1e } + .terminal-1161182100-r5 { fill: #0178d4 } + .terminal-1161182100-r6 { fill: #787878 } + .terminal-1161182100-r7 { fill: #a8a8a8 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - SelectApp + SelectApp - - - - SelectApp - - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Select - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - - - - - - - - - - - - - - - - + + + + SelectApp + + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Select + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + + + + + + + + + + + + + + + + @@ -22889,140 +22894,141 @@ font-weight: 700; } - .terminal-1328081937-matrix { + .terminal-3875007613-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1328081937-title { + .terminal-3875007613-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1328081937-r1 { fill: #c5c8c6 } - .terminal-1328081937-r2 { fill: #737373 } - .terminal-1328081937-r3 { fill: #e1e1e1;font-weight: bold } - .terminal-1328081937-r4 { fill: #323232 } - .terminal-1328081937-r5 { fill: #0178d4 } - .terminal-1328081937-r6 { fill: #121212 } - .terminal-1328081937-r7 { fill: #0053aa } - .terminal-1328081937-r8 { fill: #dde8f3;font-weight: bold } - .terminal-1328081937-r9 { fill: #e1e1e1 } - .terminal-1328081937-r10 { fill: #ddedf9 } + .terminal-3875007613-r1 { fill: #c5c8c6 } + .terminal-3875007613-r2 { fill: #737373 } + .terminal-3875007613-r3 { fill: #e1e1e1;font-weight: bold } + .terminal-3875007613-r4 { fill: #474747 } + .terminal-3875007613-r5 { fill: #0178d4 } + .terminal-3875007613-r6 { fill: #121212 } + .terminal-3875007613-r7 { fill: #0053aa } + .terminal-3875007613-r8 { fill: #dde8f3;font-weight: bold } + .terminal-3875007613-r9 { fill: #e1e1e1 } + .terminal-3875007613-r10 { fill: #323232 } + .terminal-3875007613-r11 { fill: #ddedf9 } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - TabbedApp + TabbedApp - + - - - LetoJessicaPaul - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ - - Lady Jessica - - ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ - Bene Gesserit and concubine of Leto, and mother of Paul and Alia. - - - - PaulAlia - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - - First child - - - - - - -  L  Leto  J  Jessica  P  Paul  + + + LetoJessicaPaul + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ + + Lady Jessica + + ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Bene Gesserit and concubine of Leto, and mother of Paul and Alia. + + + + PaulAlia + ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + First child + + + + + + +  L  Leto  J  Jessica  P  Paul  @@ -23682,133 +23688,133 @@ font-weight: 700; } - .terminal-1336653930-matrix { + .terminal-3137592172-matrix { font-family: Fira Code, monospace; font-size: 20px; line-height: 24.4px; font-variant-east-asian: full-width; } - .terminal-1336653930-title { + .terminal-3137592172-title { font-size: 18px; font-weight: bold; font-family: arial; } - .terminal-1336653930-r1 { fill: #e2e3e3 } - .terminal-1336653930-r2 { fill: #1a1000;font-weight: bold } - .terminal-1336653930-r3 { fill: #c5c8c6 } - .terminal-1336653930-r4 { fill: #008139 } + .terminal-3137592172-r1 { fill: #e2e3e3 } + .terminal-3137592172-r2 { fill: #211505;font-weight: bold } + .terminal-3137592172-r3 { fill: #c5c8c6 } + .terminal-3137592172-r4 { fill: #fea62b;font-weight: bold } - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - TreeApp + TreeApp - - - - ▼ Dune - └── ▼ Characters - ├── Paul - ├── Jessica - └── Chani - - - - - - - - - - - - - - - - - - + + + + ▼ Dune + ┗━━ ▼ Characters + ┣━━ Paul + ┣━━ Jessica + ┗━━ Chani + + + + + + + + + + + + + + + + + + diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py index d70fc761e..0cda94276 100644 --- a/tests/snapshot_tests/test_snapshots.py +++ b/tests/snapshot_tests/test_snapshots.py @@ -1,5 +1,4 @@ from pathlib import Path -import sys import pytest @@ -78,8 +77,7 @@ def test_switches(snap_compare): def test_input_and_focus(snap_compare): press = [ - "tab", - *"Darren", # Focus first input, write "Darren" + *"Darren", # Write "Darren" "tab", *"Burns", # Focus second input, write "Burns" ] @@ -88,7 +86,7 @@ def test_input_and_focus(snap_compare): def test_buttons_render(snap_compare): # Testing button rendering. We press tab to focus the first button too. - assert snap_compare(WIDGET_EXAMPLES_DIR / "button.py", press=["tab", "tab"]) + assert snap_compare(WIDGET_EXAMPLES_DIR / "button.py", press=["tab"]) def test_placeholder_render(snap_compare): @@ -189,7 +187,7 @@ def test_content_switcher_example_initial(snap_compare): def test_content_switcher_example_switch(snap_compare): assert snap_compare( WIDGET_EXAMPLES_DIR / "content_switcher.py", - press=["tab", "tab", "enter", "wait:500"], + press=["tab", "enter", "wait:500"], terminal_size=(50, 50), ) @@ -315,7 +313,7 @@ def test_programmatic_scrollbar_gutter_change(snap_compare): def test_borders_preview(snap_compare): - assert snap_compare(CLI_PREVIEWS_DIR / "borders.py", press=["tab", "enter"]) + assert snap_compare(CLI_PREVIEWS_DIR / "borders.py", press=["enter"]) def test_colors_preview(snap_compare): @@ -379,9 +377,7 @@ def test_disabled_widgets(snap_compare): def test_focus_component_class(snap_compare): - assert snap_compare( - SNAPSHOT_APPS_DIR / "focus_component_class.py", press=["tab", "tab"] - ) + assert snap_compare(SNAPSHOT_APPS_DIR / "focus_component_class.py", press=["tab"]) def test_line_api_scrollbars(snap_compare): diff --git a/tests/test_app.py b/tests/test_app.py index 54bde8221..9cbb82fd0 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -1,5 +1,5 @@ from textual.app import App, ComposeResult -from textual.widgets import Button +from textual.widgets import Button, Input def test_batch_update(): @@ -20,6 +20,7 @@ def test_batch_update(): class MyApp(App): def compose(self) -> ComposeResult: + yield Input() yield Button("Click me!") diff --git a/tests/test_on.py b/tests/test_on.py index 7812cd616..740af6a94 100644 --- a/tests/test_on.py +++ b/tests/test_on.py @@ -36,7 +36,7 @@ async def test_on_button_pressed() -> None: app = ButtonApp() async with app.run_test() as pilot: - await pilot.press("tab", "enter", "tab", "enter", "tab", "enter") + await pilot.press("enter", "tab", "enter", "tab", "enter") await pilot.pause() assert pressed == [ diff --git a/tests/test_paste.py b/tests/test_paste.py index 45be6d536..6cfc3951f 100644 --- a/tests/test_paste.py +++ b/tests/test_paste.py @@ -38,6 +38,7 @@ async def test_empty_paste(): app = PasteApp() async with app.run_test() as pilot: + app.set_focus(None) await pilot.press("p") assert app.query_one(MyInput).value == "" assert len(paste_events) == 1 diff --git a/tests/toggles/test_radioset.py b/tests/toggles/test_radioset.py index 95025bf37..51765b99e 100644 --- a/tests/toggles/test_radioset.py +++ b/tests/toggles/test_radioset.py @@ -39,6 +39,7 @@ async def test_radio_sets_initial_state(): async def test_click_sets_focus(): """Clicking within a radio set should set focus.""" async with RadioSetApp().run_test() as pilot: + pilot.app.set_focus(None) assert pilot.app.screen.focused is None await pilot.click("#clickme") assert pilot.app.screen.focused == pilot.app.query_one("#from_buttons") @@ -72,8 +73,6 @@ async def test_radioset_same_button_mash(): async def test_radioset_inner_navigation(): """Using the cursor keys should navigate between buttons in a set.""" async with RadioSetApp().run_test() as pilot: - assert pilot.app.screen.focused is None - await pilot.press("tab") for key, landing in ( ("down", 1), ("up", 0), @@ -88,8 +87,6 @@ async def test_radioset_inner_navigation(): == pilot.app.query_one("#from_buttons").children[landing] ) async with RadioSetApp().run_test() as pilot: - assert pilot.app.screen.focused is None - await pilot.press("tab") assert pilot.app.screen.focused is pilot.app.screen.query_one("#from_buttons") await pilot.press("tab") assert pilot.app.screen.focused is pilot.app.screen.query_one("#from_strings") @@ -101,8 +98,6 @@ async def test_radioset_inner_navigation(): async def test_radioset_breakout_navigation(): """Shift/Tabbing while in a radioset should move to the previous/next focsuable after the set itself.""" async with RadioSetApp().run_test() as pilot: - assert pilot.app.screen.focused is None - await pilot.press("tab") assert pilot.app.screen.focused is pilot.app.query_one("#from_buttons") await pilot.press("tab") assert pilot.app.screen.focused is pilot.app.query_one("#from_strings") From 38f9500642c7076497a99a8c8c42d279407bbec3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Gir=C3=A3o=20Serr=C3=A3o?= <5621605+rodrigogiraoserrao@users.noreply.github.com> Date: Wed, 17 May 2023 11:35:10 +0100 Subject: [PATCH 6/6] Fix test. --- tests/snapshot_tests/test_snapshots.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py index 6ced5f476..bdedbced3 100644 --- a/tests/snapshot_tests/test_snapshots.py +++ b/tests/snapshot_tests/test_snapshots.py @@ -514,6 +514,5 @@ def test_select_rebuild(snap_compare): # https://github.com/Textualize/textual/issues/2557 assert snap_compare( SNAPSHOT_APPS_DIR / "select_rebuild.py", - press=["tab", "space", "escape", "tab", "enter", "tab", "space"] + press=["space", "escape", "tab", "enter", "tab", "space"], ) -