Repository: zulip/zulip-terminal

Issue:
ZT Crashes when viewing a message in browser in MacOS.
<img width="1031" alt="Screenshot 2024-02-15 at 9 44 55 PM" src="https://github.com/zulip/zulip-terminal/assets/71403193/deeadd45-decb-42f5-880c-30f709268a29">


ZT crashes when viewing a message in browser on MacOS.
My OS version = Ventura 13.6
Python version = 3.9

This might be a problem for other OS too. 

## Steps to replicate: 
1. Open ZT
2. Open message information popup
3. Select `open in web browser`

Comments:

Patch:
diff --git a/zulipterminal/core.py b/zulipterminal/core.py
index ddc7e89..1e11354 100644
--- a/zulipterminal/core.py
+++ b/zulipterminal/core.py
@@ -414,11 +414,14 @@ class Controller:
             # Suppress stdout and stderr when opening browser
             with suppress_output():
                 browser_controller.open(url)
+
+                # MacOS using Python version < 3.11 has no "name" attribute
+                # - https://github.com/python/cpython/issues/82828
+                # - https://github.com/python/cpython/issues/87590
+                # Use a default value if missing, for macOS, and potential later issues
+                browser_name = getattr(browser_controller, "name", "default browser")
                 self.report_success(
-                    [
-                        "The link was successfully opened using "
-                        f"{browser_controller.name}"
-                    ]
+                    [f"The link was successfully opened using {browser_name}"]
                 )
         except webbrowser.Error as e:
             # Set a footer text if no runnable browser is located


Test patch:
diff --git a/tests/core/test_core.py b/tests/core/test_core.py
index 033f126..be05d49 100644
--- a/tests/core/test_core.py
+++ b/tests/core/test_core.py
@@ -406,15 +406,24 @@ class TestController:
         assert popup.call_args_list[0][0][1] == "area:error"
 
     @pytest.mark.parametrize(
-        "url",
+        "url, webbrowser_name, expected_webbrowser_name",
         [
-            "https://chat.zulip.org/#narrow/stream/test",
-            "https://chat.zulip.org/user_uploads/sent/abcd/efg.png",
-            "https://github.com/",
+            ("https://chat.zulip.org/#narrow/stream/test", "chrome", "chrome"),
+            (
+                "https://chat.zulip.org/user_uploads/sent/abcd/efg.png",
+                "mozilla",
+                "mozilla",
+            ),
+            ("https://github.com/", None, "default browser"),
         ],
     )
     def test_open_in_browser_success(
-        self, mocker: MockerFixture, controller: Controller, url: str
+        self,
+        mocker: MockerFixture,
+        controller: Controller,
+        url: str,
+        webbrowser_name: Optional[str],
+        expected_webbrowser_name: str,
     ) -> None:
         # Set DISPLAY environ to be able to run test in CI
         os.environ["DISPLAY"] = ":0"
@@ -422,11 +431,16 @@ class TestController:
         mock_get = mocker.patch(MODULE + ".webbrowser.get")
         mock_open = mock_get.return_value.open
 
+        if webbrowser_name is None:
+            del mock_get.return_value.name
+        else:
+            mock_get.return_value.name = webbrowser_name
+
         controller.open_in_browser(url)
 
         mock_open.assert_called_once_with(url)
         mocked_report_success.assert_called_once_with(
-            [f"The link was successfully opened using {mock_get.return_value.name}"]
+            [f"The link was successfully opened using {expected_webbrowser_name}"]
         )
 
     def test_open_in_browser_fail__no_browser_controller(