diff --git a/changelog/13896.bugfix.rst b/changelog/13896.bugfix.rst new file mode 100644 index 00000000000..821af0c96b4 --- /dev/null +++ b/changelog/13896.bugfix.rst @@ -0,0 +1 @@ +The terminal progress plugin added in pytest 9.0 is now automatically disabled when iTerm2 is detected, it generated desktop notifications instead of the desired functionality. diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index 158558b4571..4517b05bdee 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -16,6 +16,7 @@ import datetime from functools import partial import inspect +import os from pathlib import Path import platform import sys @@ -299,8 +300,15 @@ def mywriter(tags, args): config.trace.root.setprocessor("pytest:config", mywriter) if reporter.isatty(): - plugin = TerminalProgressPlugin(reporter) - config.pluginmanager.register(plugin, "terminalprogress") + # Some terminals interpret OSC 9;4 as desktop notification, + # skip on those we know (#13896). + should_skip_terminal_progress = ( + # iTerm2 (reported on version 3.6.5). + "ITERM_SESSION_ID" in os.environ + ) + if not should_skip_terminal_progress: + plugin = TerminalProgressPlugin(reporter) + config.pluginmanager.register(plugin, "terminalprogress") def getreportopt(config: Config) -> str: diff --git a/testing/test_terminal.py b/testing/test_terminal.py index ee540b65135..a981e14f0a2 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -3443,6 +3443,17 @@ def test_disabled_for_non_tty(self, pytester: pytest.Pytester) -> None: plugin = config.pluginmanager.get_plugin("terminalprogress") assert plugin is None + def test_disabled_for_iterm2(self, pytester: pytest.Pytester, monkeypatch) -> None: + """Should not register the plugin on iTerm2 terminal since it interprets + OSC 9;4 as desktop notifications, not progress (#13896).""" + monkeypatch.setenv( + "ITERM_SESSION_ID", "w0t1p0:3DB6DF06-FE11-40C3-9A66-9E10A193A632" + ) + with patch.object(sys.stdout, "isatty", return_value=True): + config = pytester.parseconfigure() + plugin = config.pluginmanager.get_plugin("terminalprogress") + assert plugin is None + @pytest.mark.parametrize( ["state", "progress", "expected"], [