Repository: zulip/zulip-terminal
Pull request #1514 (2024-06-06 23:16:07)

Break down the GO_BACK command into separate commands
### What does this PR do, and why?
Breaks GO_BACK command into the following commands:
- CLEAR_SEARCH (clears search box and search list of current panel)
- EXIT_COMPOSE (clears compose box state and closes it)
- EXIT_POPUP (closes the currently open popup)

This would enable using more specific help texts, categories and context.
And clarifies the purposes of the key better for users and developers.

I've kept these as separate commits for the sake of readability. Introducing each command in its own commit, then finally removing GO_BACK command.
I could break #1497 into commits similar to this one for readability, if necessary.
I've kept this as a separate PR as it's an independent change, even though the motivation is shared.

### External discussion & connections
- [x] Discussed in **#zulip-terminal** in [`re-categorize`](https://chat.zulip.org/#narrow/stream/206-zulip-terminal/topic/Re-Categorization.20of.20Hotkeys/near/1793697)
- [ ] Fully fixes #
- [ ] Partially fixes issue #
- [ ] Builds upon previous unmerged work in PR #
- [x] Is a follow-up to work in PR #1497
- [ ] Requires merge of PR #
- [ ] Merge will enable work on #

### How did you test this?
- [ ] Manually - Behavioral changes
- [ ] Manually - Visual changes
- [ ] Adapting existing automated tests
- [ ] Adding automated tests for new behavior (or missing tests)
- [x] Existing automated tests should already cover this (*only a refactor of tested code*)

### Self-review checklist for each commit
- [x] It is a [minimal coherent idea](https://github.com/zulip/zulip-terminal#structuring-commits---speeding-up-reviews-merging--development)
- [x] It has a commit summary following the [documented style](https://github.com/zulip/zulip-terminal#structuring-commits---speeding-up-reviews-merging--development) (title & body)
- [ ] It has a commit summary describing the  motivation and reasoning for the change
- [x] It individually passes linting and tests
- [ ] It contains test additions for any new behavior
- [x] It flows clearly from a previous branch commit, and/or prepares for the next commit

zulipbot: Hello @zulip/server-refactoring members, this pull request was labeled with the "area: refactoring" label, so you may want to check it out!

<!-- areaLabelAddition -->

rsashank: LGTM! The intention seems clear since we're aiming for contextual help.

Just a note: Either this PR or #1442 will need to handle conflicts in a rebase, depending on which gets merged first.
zulipbot: Heads up @Niloth-p, we just merged some commits that conflict with the changes you made in this pull request! You can review this repository's [recent commits](https://github.com/zulip/zulip-terminal/commits/main) to see where the conflicts occur. Please rebase your feature branch against the `upstream/main` branch and [resolve](https://zulip.readthedocs.io/en/latest/git/troubleshooting.html#recover-from-a-git-rebase-failure) your pull request's merge conflicts accordingly.

<!-- mergeConflictWarning -->

neiljp: @Niloth-p I agree with @zormit - this is clear and easy to read :+1:

The changes I pushed back with were only structural/text (the code overall is identical):
- squash the last commit with the smaller of the two later commits, to avoid a state where we have a menu entry that does nothing
- adjust some commit text (these change the UI, so aren't strictly refactors
- added some file names in the commit titles

Patch:
diff --git a/docs/hotkeys.md b/docs/hotkeys.md
index 1272bfc..d1cd722 100644
--- a/docs/hotkeys.md
+++ b/docs/hotkeys.md
@@ -8,7 +8,6 @@
 |Show/hide Help Menu|<kbd>?</kbd>|
 |Show/hide Markdown Help Menu|<kbd>Meta</kbd> + <kbd>m</kbd>|
 |Show/hide About Menu|<kbd>Meta</kbd> + <kbd>?</kbd>|
-|Go back|<kbd>Esc</kbd>|
 |Open draft message saved in this session|<kbd>d</kbd>|
 |Copy information from About Menu to clipboard|<kbd>c</kbd>|
 |Redraw screen|<kbd>Ctrl</kbd> + <kbd>l</kbd>|
@@ -18,6 +17,7 @@
 ## Navigation
 |Command|Key Combination|
 | :--- | :---: |
+|Close popup|<kbd>Esc</kbd>|
 |Go up / Previous message|<kbd>Up</kbd> / <kbd>k</kbd>|
 |Go down / Next message|<kbd>Down</kbd> / <kbd>j</kbd>|
 |Go left|<kbd>Left</kbd> / <kbd>h</kbd>|
@@ -42,6 +42,7 @@
 |Search topics in a stream|<kbd>q</kbd>|
 |Search emojis from emoji picker|<kbd>p</kbd>|
 |Submit search and browse results|<kbd>Enter</kbd>|
+|Clear search in current panel|<kbd>Esc</kbd>|
 
 ## Message actions
 |Command|Key Combination|
@@ -85,6 +86,7 @@
 |Autocomplete @mentions, #stream_names, :emoji: and topics|<kbd>Ctrl</kbd> + <kbd>f</kbd>|
 |Cycle through autocomplete suggestions in reverse|<kbd>Ctrl</kbd> + <kbd>r</kbd>|
 |Narrow to compose box message recipient|<kbd>Meta</kbd> + <kbd>.</kbd>|
+|Exit message compose box|<kbd>Esc</kbd>|
 |Insert new line|<kbd>Enter</kbd>|
 
 ## Editor: Navigation
diff --git a/tools/lint-hotkeys b/tools/lint-hotkeys
index 503a024..83a7db0 100755
--- a/tools/lint-hotkeys
+++ b/tools/lint-hotkeys
@@ -23,7 +23,7 @@ SCRIPT_NAME = PurePath(__file__).name
 HELP_TEXT_STYLE = re.compile(r"^[a-zA-Z /()',&@#:_-]*$")
 
 # Exclude keys from duplicate keys checking
-KEYS_TO_EXCLUDE = ["q", "e", "m", "r"]
+KEYS_TO_EXCLUDE = ["q", "e", "m", "r", "Esc"]
 
 
 def main(fix: bool) -> None:
diff --git a/zulipterminal/config/keys.py b/zulipterminal/config/keys.py
index 3306f68..254778a 100644
--- a/zulipterminal/config/keys.py
+++ b/zulipterminal/config/keys.py
@@ -46,12 +46,6 @@ KEY_BINDINGS: Dict[str, KeyBinding] = {
         'help_text': 'Show/hide About Menu',
         'key_category': 'general',
     },
-    'GO_BACK': {
-        'keys': ['esc'],
-        'help_text': 'Go back',
-        'excluded_from_random_tips': False,
-        'key_category': 'general',
-    },
     'OPEN_DRAFT': {
         'keys': ['d'],
         'help_text': 'Open draft message saved in this session',
@@ -62,6 +56,11 @@ KEY_BINDINGS: Dict[str, KeyBinding] = {
         'help_text': 'Copy information from About Menu to clipboard',
         'key_category': 'general',
     },
+    'EXIT_POPUP': {
+        'keys': ['esc'],
+        'help_text': 'Close popup',
+        'key_category': 'navigation',
+    },
     'GO_UP': {
         'keys': ['up', 'k'],
         'help_text': 'Go up / Previous message',
@@ -183,6 +182,11 @@ KEY_BINDINGS: Dict[str, KeyBinding] = {
         'help_text': 'Narrow to compose box message recipient',
         'key_category': 'msg_compose',
     },
+    'EXIT_COMPOSE': {
+        'keys': ['esc'],
+        'help_text': 'Exit message compose box',
+        'key_category': 'msg_compose',
+    },
     'TOGGLE_NARROW': {
         'keys': ['z'],
         'help_text':
@@ -260,6 +264,11 @@ KEY_BINDINGS: Dict[str, KeyBinding] = {
         'help_text': 'Submit search and browse results',
         'key_category': 'searching',
     },
+    'CLEAR_SEARCH': {
+        'keys': ['esc'],
+        'help_text': 'Clear search in current panel',
+        'key_category': 'searching',
+    },
     'TOGGLE_MUTE_STREAM': {
         'keys': ['m'],
         'help_text': 'Mute/unmute streams',
diff --git a/zulipterminal/model.py b/zulipterminal/model.py
index f917a56..1d7688c 100644
--- a/zulipterminal/model.py
+++ b/zulipterminal/model.py
@@ -1714,7 +1714,7 @@ class Model:
                 "Press '{}' to close this window."
             )
             notice = notice_template.format(
-                failed_command, primary_display_key_for_command("GO_BACK")
+                failed_command, primary_display_key_for_command("EXIT_POPUP")
             )
             self.controller.popup_with_message(notice, width=50)
             self.controller.update_screen()
diff --git a/zulipterminal/ui_tools/boxes.py b/zulipterminal/ui_tools/boxes.py
index 91e2f80..fa3dc1f 100644
--- a/zulipterminal/ui_tools/boxes.py
+++ b/zulipterminal/ui_tools/boxes.py
@@ -775,7 +775,7 @@ class WriteBox(urwid.Pile):
             if success:
                 self.msg_write_box.edit_text = ""
                 if self.msg_edit_state is not None:
-                    self.keypress(size, primary_key_for_command("GO_BACK"))
+                    self.keypress(size, primary_key_for_command("EXIT_COMPOSE"))
                     assert self.msg_edit_state is None
         elif is_command_key("NARROW_MESSAGE_RECIPIENT", key):
             if self.compose_box_status == "open_with_stream":
@@ -798,7 +798,7 @@ class WriteBox(urwid.Pile):
                     self.view.controller.report_error(
                         "Cannot narrow to message without specifying recipients."
                     )
-        elif is_command_key("GO_BACK", key):
+        elif is_command_key("EXIT_COMPOSE", key):
             self.send_stop_typing_status()
             self._set_compose_attributes_to_defaults()
             self.view.controller.exit_editor_mode()
@@ -948,7 +948,7 @@ class MessageSearchBox(urwid.Pile):
     def keypress(self, size: urwid_Size, key: str) -> Optional[str]:
         if (
             is_command_key("EXECUTE_SEARCH", key) and self.text_box.edit_text == ""
-        ) or is_command_key("GO_BACK", key):
+        ) or is_command_key("CLEAR_SEARCH", key):
             self.text_box.set_edit_text("")
             self.controller.exit_editor_mode()
             self.controller.view.middle_column.set_focus("body")
@@ -1004,13 +1004,13 @@ class PanelSearchBox(ReadlineEdit):
     def keypress(self, size: urwid_Size, key: str) -> Optional[str]:
         if (
             is_command_key("EXECUTE_SEARCH", key) and self.get_edit_text() == ""
-        ) or is_command_key("GO_BACK", key):
+        ) or is_command_key("CLEAR_SEARCH", key):
             self.panel_view.view.controller.exit_editor_mode()
             self.reset_search_text()
             self.panel_view.set_focus("body")
             # Don't call 'Esc' when inside a popup search-box.
             if not self.panel_view.view.controller.is_any_popup_open():
-                self.panel_view.keypress(size, primary_key_for_command("GO_BACK"))
+                self.panel_view.keypress(size, primary_key_for_command("CLEAR_SEARCH"))
         elif is_command_key("EXECUTE_SEARCH", key) and not self.panel_view.empty_search:
             self.panel_view.view.controller.exit_editor_mode()
             self.set_caption([("filter_results", " Search Results "), " "])
diff --git a/zulipterminal/ui_tools/views.py b/zulipterminal/ui_tools/views.py
index ddb8e8d..c2034b3 100644
--- a/zulipterminal/ui_tools/views.py
+++ b/zulipterminal/ui_tools/views.py
@@ -398,7 +398,7 @@ class StreamsView(urwid.Frame):
             self.stream_search_box.set_caption(" ")
             self.view.controller.enter_editor_mode_with(self.stream_search_box)
             return key
-        elif is_command_key("GO_BACK", key):
+        elif is_command_key("CLEAR_SEARCH", key):
             self.stream_search_box.reset_search_text()
             self.log.clear()
             self.log.extend(self.streams_btn_list)
@@ -518,7 +518,7 @@ class TopicsView(urwid.Frame):
             self.topic_search_box.set_caption(" ")
             self.view.controller.enter_editor_mode_with(self.topic_search_box)
             return key
-        elif is_command_key("GO_BACK", key):
+        elif is_command_key("CLEAR_SEARCH", key):
             self.topic_search_box.reset_search_text()
             self.log.clear()
             self.log.extend(self.topics_btn_list)
@@ -759,7 +759,7 @@ class RightColumnView(urwid.Frame):
             self.user_search.set_caption(" ")
             self.view.controller.enter_editor_mode_with(self.user_search)
             return key
-        elif is_command_key("GO_BACK", key):
+        elif is_command_key("CLEAR_SEARCH", key):
             self.user_search.reset_search_text()
             self.allow_update_user_list = True
             self.body = UsersView(self.view.controller, self.users_btn_list)
@@ -1058,7 +1058,7 @@ class PopUpView(urwid.Frame):
         return widgets
 
     def keypress(self, size: urwid_Size, key: str) -> str:
-        if is_command_key("GO_BACK", key) or is_command_key(self.command, key):
+        if is_command_key("EXIT_POPUP", key) or is_command_key(self.command, key):
             self.controller.exit_popup()
 
         return super().keypress(size, key)
@@ -1073,7 +1073,7 @@ class NoticeView(PopUpView):
             urwid.Padding(urwid.Text(notice_text), left=1, right=1),
             urwid.Divider(),
         ]
-        super().__init__(controller, widgets, "GO_BACK", width, title)
+        super().__init__(controller, widgets, "EXIT_POPUP", width, title)
 
 
 class AboutView(PopUpView):
@@ -1351,7 +1351,7 @@ class PopUpConfirmationView(urwid.Overlay):
         self.controller.exit_popup()
 
     def keypress(self, size: urwid_Size, key: str) -> str:
-        if is_command_key("GO_BACK", key):
+        if is_command_key("EXIT_POPUP", key):
             self.controller.exit_popup()
         return super().keypress(size, key)
 
@@ -1561,7 +1561,7 @@ class StreamMembersView(PopUpView):
         super().__init__(controller, widgets, "STREAM_INFO", popup_width, title)
 
     def keypress(self, size: urwid_Size, key: str) -> str:
-        if is_command_key("GO_BACK", key) or is_command_key("STREAM_MEMBERS", key):
+        if is_command_key("EXIT_POPUP", key) or is_command_key("STREAM_MEMBERS", key):
             self.controller.show_stream_info(stream_id=self.stream_id)
             return key
         return super().keypress(size, key)
@@ -1895,7 +1895,7 @@ class EditHistoryView(PopUpView):
         return author_prefix
 
     def keypress(self, size: urwid_Size, key: str) -> str:
-        if is_command_key("GO_BACK", key) or is_command_key("EDIT_HISTORY", key):
+        if is_command_key("EXIT_POPUP", key) or is_command_key("EDIT_HISTORY", key):
             self.controller.show_msg_info(
                 msg=self.message,
                 topic_links=self.topic_links,
@@ -1937,7 +1937,7 @@ class FullRenderedMsgView(PopUpView):
         )
 
     def keypress(self, size: urwid_Size, key: str) -> str:
-        if is_command_key("GO_BACK", key) or is_command_key(
+        if is_command_key("EXIT_POPUP", key) or is_command_key(
             "FULL_RENDERED_MESSAGE", key
         ):
             self.controller.show_msg_info(
@@ -1989,7 +1989,7 @@ class FullRawMsgView(PopUpView):
         )
 
     def keypress(self, size: urwid_Size, key: str) -> str:
-        if is_command_key("GO_BACK", key) or is_command_key("FULL_RAW_MESSAGE", key):
+        if is_command_key("EXIT_POPUP", key) or is_command_key("FULL_RAW_MESSAGE", key):
             self.controller.show_msg_info(
                 msg=self.message,
                 topic_links=self.topic_links,
@@ -2144,7 +2144,7 @@ class EmojiPickerView(PopUpView):
             self.emoji_search.set_caption(" ")
             self.controller.enter_editor_mode_with(self.emoji_search)
             return key
-        elif is_command_key("GO_BACK", key) or is_command_key("ADD_REACTION", key):
+        elif is_command_key("EXIT_POPUP", key) or is_command_key("ADD_REACTION", key):
             for emoji_code, emoji_name in self.selected_emojis.items():
                 self.controller.model.toggle_message_reaction(self.message, emoji_name)
             self.emoji_search.reset_search_text()


Test patch:
diff --git a/tests/ui/test_ui_tools.py b/tests/ui/test_ui_tools.py
index 18d2ef2..0a4d9ec 100644
--- a/tests/ui/test_ui_tools.py
+++ b/tests/ui/test_ui_tools.py
@@ -559,8 +559,8 @@ class TestStreamsView:
             stream_view.stream_search_box
         )
 
-    @pytest.mark.parametrize("key", keys_for_command("GO_BACK"))
-    def test_keypress_GO_BACK(self, mocker, stream_view, key, widget_size):
+    @pytest.mark.parametrize("key", keys_for_command("CLEAR_SEARCH"))
+    def test_keypress_CLEAR_SEARCH(self, mocker, stream_view, key, widget_size):
         size = widget_size(stream_view)
         mocker.patch.object(stream_view, "set_focus")
         mocker.patch(VIEWS + ".urwid.Frame.keypress")
@@ -725,8 +725,8 @@ class TestTopicsView:
             topic_view.topic_search_box
         )
 
-    @pytest.mark.parametrize("key", keys_for_command("GO_BACK"))
-    def test_keypress_GO_BACK(self, mocker, topic_view, key, widget_size):
+    @pytest.mark.parametrize("key", keys_for_command("CLEAR_SEARCH"))
+    def test_keypress_CLEAR_SEARCH(self, mocker, topic_view, key, widget_size):
         size = widget_size(topic_view)
         mocker.patch(VIEWS + ".TopicsView.set_focus")
         mocker.patch(VIEWS + ".urwid.Frame.keypress")
@@ -1105,8 +1105,8 @@ class TestRightColumnView:
             right_col_view.user_search
         )
 
-    @pytest.mark.parametrize("key", keys_for_command("GO_BACK"))
-    def test_keypress_GO_BACK(self, right_col_view, mocker, key, widget_size):
+    @pytest.mark.parametrize("key", keys_for_command("CLEAR_SEARCH"))
+    def test_keypress_CLEAR_SEARCH(self, right_col_view, mocker, key, widget_size):
         size = widget_size(right_col_view)
         mocker.patch(VIEWS + ".UsersView")
         mocker.patch(VIEWS + ".RightColumnView.set_focus")
diff --git a/tests/ui_tools/test_boxes.py b/tests/ui_tools/test_boxes.py
index b6c763c..4b28a1e 100644
--- a/tests/ui_tools/test_boxes.py
+++ b/tests/ui_tools/test_boxes.py
@@ -235,7 +235,7 @@ class TestWriteBox:
 
         assert not write_box.model.send_private_message.called
 
-    @pytest.mark.parametrize("key", keys_for_command("GO_BACK"))
+    @pytest.mark.parametrize("key", keys_for_command("EXIT_COMPOSE"))
     def test__compose_attributes_reset_for_private_compose(
         self,
         key: str,
@@ -256,7 +256,7 @@ class TestWriteBox:
         assert write_box.msg_write_box.edit_text == ""
         assert write_box.compose_box_status == "closed"
 
-    @pytest.mark.parametrize("key", keys_for_command("GO_BACK"))
+    @pytest.mark.parametrize("key", keys_for_command("EXIT_COMPOSE"))
     def test__compose_attributes_reset_for_stream_compose(
         self,
         key: str,
@@ -1516,7 +1516,7 @@ class TestWriteBox:
             (primary_key_for_command("AUTOCOMPLETE"), True, True, False),
             (primary_key_for_command("AUTOCOMPLETE_REVERSE"), True, True, False),
             # footer resets
-            (primary_key_for_command("GO_BACK"), True, False, True),
+            (primary_key_for_command("EXIT_COMPOSE"), True, False, True),
             ("space", True, False, True),
             ("k", True, False, True),
         ],
@@ -1858,8 +1858,8 @@ class TestPanelSearchBox:
             panel_view.set_focus.assert_not_called()
             panel_view.body.set_focus.assert_not_called()
 
-    @pytest.mark.parametrize("back_key", keys_for_command("GO_BACK"))
-    def test_keypress_GO_BACK(
+    @pytest.mark.parametrize("back_key", keys_for_command("CLEAR_SEARCH"))
+    def test_keypress_CLEAR_SEARCH(
         self,
         panel_search_box: PanelSearchBox,
         back_key: str,
diff --git a/tests/ui_tools/test_popups.py b/tests/ui_tools/test_popups.py
index ee412f6..d58b6c3 100644
--- a/tests/ui_tools/test_popups.py
+++ b/tests/ui_tools/test_popups.py
@@ -78,8 +78,8 @@ class TestPopUpConfirmationView:
         self.callback.assert_not_called()
         assert self.controller.exit_popup.called
 
-    @pytest.mark.parametrize("key", keys_for_command("GO_BACK"))
-    def test_exit_popup_GO_BACK(
+    @pytest.mark.parametrize("key", keys_for_command("EXIT_POPUP"))
+    def test_exit_popup_EXIT_POPUP(
         self,
         popup_view: PopUpConfirmationView,
         key: str,
@@ -133,8 +133,8 @@ class TestPopUpView:
             self.pop_up_view.body, header=mocker.ANY, footer=mocker.ANY
         )
 
-    @pytest.mark.parametrize("key", keys_for_command("GO_BACK"))
-    def test_keypress_GO_BACK(
+    @pytest.mark.parametrize("key", keys_for_command("EXIT_POPUP"))
+    def test_keypress_EXIT_POPUP(
         self,
         key: str,
         widget_size: Callable[[Widget], urwid_Size],
@@ -210,7 +210,7 @@ class TestAboutView:
         )
 
     @pytest.mark.parametrize(
-        "key", {*keys_for_command("GO_BACK"), *keys_for_command("ABOUT")}
+        "key", {*keys_for_command("EXIT_POPUP"), *keys_for_command("ABOUT")}
     )
     def test_keypress_exit_popup(
         self, key: str, widget_size: Callable[[Widget], urwid_Size]
@@ -467,7 +467,7 @@ class TestUserInfoView:
         assert custom_profile_data == {}
 
     @pytest.mark.parametrize(
-        "key", {*keys_for_command("GO_BACK"), *keys_for_command("USER_INFO")}
+        "key", {*keys_for_command("EXIT_POPUP"), *keys_for_command("USER_INFO")}
     )
     def test_keypress_exit_popup(
         self, key: str, widget_size: Callable[[Widget], urwid_Size]
@@ -540,7 +540,7 @@ class TestFullRenderedMsgView:
         "key",
         {
             *keys_for_command("FULL_RENDERED_MESSAGE"),
-            *keys_for_command("GO_BACK"),
+            *keys_for_command("EXIT_POPUP"),
         },
     )
     def test_keypress_show_msg_info(
@@ -616,7 +616,7 @@ class TestFullRawMsgView:
         "key",
         {
             *keys_for_command("FULL_RAW_MESSAGE"),
-            *keys_for_command("GO_BACK"),
+            *keys_for_command("EXIT_POPUP"),
         },
     )
     def test_keypress_show_msg_info(
@@ -688,7 +688,7 @@ class TestEditHistoryView:
         assert not self.controller.exit_popup.called
 
     @pytest.mark.parametrize(
-        "key", {*keys_for_command("EDIT_HISTORY"), *keys_for_command("GO_BACK")}
+        "key", {*keys_for_command("EDIT_HISTORY"), *keys_for_command("EXIT_POPUP")}
     )
     def test_keypress_show_msg_info(
         self, key: str, widget_size: Callable[[Widget], urwid_Size]
@@ -911,7 +911,7 @@ class TestMarkdownHelpView:
         assert not self.controller.exit_popup.called
 
     @pytest.mark.parametrize(
-        "key", {*keys_for_command("GO_BACK"), *keys_for_command("MARKDOWN_HELP")}
+        "key", {*keys_for_command("EXIT_POPUP"), *keys_for_command("MARKDOWN_HELP")}
     )
     def test_keypress_exit_popup(
         self, key: str, widget_size: Callable[[Widget], urwid_Size]
@@ -942,7 +942,7 @@ class TestHelpView:
         assert not self.controller.exit_popup.called
 
     @pytest.mark.parametrize(
-        "key", {*keys_for_command("GO_BACK"), *keys_for_command("HELP")}
+        "key", {*keys_for_command("EXIT_POPUP"), *keys_for_command("HELP")}
     )
     def test_keypress_exit_popup(
         self, key: str, widget_size: Callable[[Widget], urwid_Size]
@@ -1113,7 +1113,7 @@ class TestMsgInfoView:
         )
 
     @pytest.mark.parametrize(
-        "key", {*keys_for_command("GO_BACK"), *keys_for_command("MSG_INFO")}
+        "key", {*keys_for_command("EXIT_POPUP"), *keys_for_command("MSG_INFO")}
     )
     def test_keypress_exit_popup(
         self, key: str, widget_size: Callable[[Widget], urwid_Size]
@@ -1550,7 +1550,7 @@ class TestStreamInfoView:
         assert footlinks_width == expected_footlinks_width
 
     @pytest.mark.parametrize(
-        "key", {*keys_for_command("GO_BACK"), *keys_for_command("STREAM_INFO")}
+        "key", {*keys_for_command("EXIT_POPUP"), *keys_for_command("STREAM_INFO")}
     )
     def test_keypress_exit_popup(
         self, key: str, widget_size: Callable[[Widget], urwid_Size]
@@ -1615,7 +1615,7 @@ class TestStreamMembersView:
         self.stream_members_view = StreamMembersView(self.controller, stream_id)
 
     @pytest.mark.parametrize(
-        "key", {*keys_for_command("GO_BACK"), *keys_for_command("STREAM_MEMBERS")}
+        "key", {*keys_for_command("EXIT_POPUP"), *keys_for_command("STREAM_MEMBERS")}
     )
     def test_keypress_exit_popup(
         self, key: str, widget_size: Callable[[Widget], urwid_Size]
@@ -1730,7 +1730,7 @@ class TestEmojiPickerView:
         assert self.emoji_picker_view.get_focus() == "header"
 
     @pytest.mark.parametrize(
-        "key", {*keys_for_command("GO_BACK"), *keys_for_command("ADD_REACTION")}
+        "key", {*keys_for_command("EXIT_POPUP"), *keys_for_command("ADD_REACTION")}
     )
     def test_keypress_exit_called(
         self, key: str, widget_size: Callable[[Widget], urwid_Size]