diff --git a/AUTHORS b/AUTHORS index bd1e27cb37d..71df6064dfd 100644 --- a/AUTHORS +++ b/AUTHORS @@ -204,6 +204,7 @@ Gregory Lee Grig Gheorghiu Grigorii Eremeev (budulianin) Guido Wesdorp +Guillaume Marty Guoqiang Zhang hfycium Hamza Mobeen diff --git a/changelog/15216.bugfix.rst b/changelog/15216.bugfix.rst new file mode 100644 index 00000000000..43aca283bf2 --- /dev/null +++ b/changelog/15216.bugfix.rst @@ -0,0 +1 @@ +The lines of the "short test summary info" section are now trimmed to the terminal width when color output is enabled -- previously the color escape codes broke the width computation, so the lines overflowed the terminal. diff --git a/src/_pytest/terminal.py b/src/_pytest/terminal.py index b77a649d28a..9aa886c5421 100644 --- a/src/_pytest/terminal.py +++ b/src/_pytest/terminal.py @@ -18,6 +18,7 @@ import inspect from pathlib import Path import platform +import re import sys import textwrap from typing import Any @@ -1571,6 +1572,10 @@ def _format_trimmed(format: str, msg: str, available_width: int) -> str | None: return format.format(msg) +# Escape sequences added by TerminalWriter.markup(), which take no columns. +_ANSI_ESCAPE_SEQ = re.compile(r"\x1b\[[\d;]*m") + + def _get_line_with_reprcrash_message( config: Config, rep: BaseReport, tw: TerminalWriter, word_markup: dict[str, bool] ) -> str: @@ -1582,7 +1587,7 @@ def _get_line_with_reprcrash_message( node = _get_node_id_with_markup(tw, config, rep) line = f"{word} {node}" - line_width = wcswidth(line) + line_width = wcswidth(_ANSI_ESCAPE_SEQ.sub("", line)) msg: str | None try: diff --git a/testing/test_terminal.py b/testing/test_terminal.py index 21b0557a470..d0421ba29f8 100644 --- a/testing/test_terminal.py +++ b/testing/test_terminal.py @@ -6,6 +6,7 @@ from io import StringIO import os from pathlib import Path +import re import sys import textwrap from types import SimpleNamespace @@ -1409,6 +1410,27 @@ def test_fail_extra_reporting( ) +def test_fail_extra_reporting_truncation_with_color( + pytester: Pytester, monkeypatch: MonkeyPatch +) -> None: + """The short summary line is trimmed to the terminal width also when + color is enabled: the escape codes of the markup take no columns.""" + monkeypatch.delenv("CI", raising=False) + monkeypatch.setenv("COLUMNS", "80") + pytester.makepyfile("def test_this(): assert 0, 'this_failed' * 100") + + def summary_lines(*args: str) -> list[str]: + result = pytester.runpytest(*args) + lines = [re.sub(r"\x1b\[[\d;]*m", "", line) for line in result.stdout.lines] + return [line for line in lines if line.startswith("FAILED ")] + + expected = summary_lines("--color=no") + assert len(expected) == 1 + assert expected[0].endswith(" - Assert...") + assert len(expected[0]) == 80 + assert summary_lines("--color=yes") == expected + + def test_fail_reporting_on_pass(pytester: Pytester) -> None: pytester.makepyfile("def test_this(): assert 1") result = pytester.runpytest("-rf")