diff --git a/src/pytest_html/basereport.py b/src/pytest_html/basereport.py
index cfcc74b2..a27bf143 100644
--- a/src/pytest_html/basereport.py
+++ b/src/pytest_html/basereport.py
@@ -42,12 +42,20 @@ def css(self):
return
def _asset_filename(self, test_id, extra_index, test_index, file_extension):
- return "{}_{}_{}.{}".format(
+ filename = "{}_{}_{}.{}".format(
re.sub(r"[^\w.]", "_", test_id),
str(extra_index),
str(test_index),
file_extension,
- )[-self._max_asset_filename_length :]
+ )
+ max_length = self._max_asset_filename_length
+ assets_dir = getattr(self, "_assets_path", None)
+ if assets_dir is not None:
+ # Files are written under this directory (see Report._write_content).
+ # Reserve the directory name plus separator so the relative path
+ # stays within max_asset_filename_length on path-limited systems.
+ max_length -= len(assets_dir.name) + 1
+ return filename[-max(1, max_length) :]
def _generate_report(self, self_contained=False):
generated = datetime.datetime.now()
diff --git a/testing/legacy_test_pytest_html.py b/testing/legacy_test_pytest_html.py
index 08ad208d..f2fe3db4 100644
--- a/testing/legacy_test_pytest_html.py
+++ b/testing/legacy_test_pytest_html.py
@@ -681,8 +681,9 @@ def {test_name}():
"""
)
result, html = run(testdir, "report.html")
+ truncated_length = max(1, max_asset_filename_length - len("assets/"))
file_name = f"test_very_long_test_name.py__{test_name}_0_0.png"[
- -max_asset_filename_length:
+ -truncated_length:
]
src = "assets/" + file_name
link = f''
diff --git a/testing/test_unit.py b/testing/test_unit.py
index 1ea945ea..eaef969c 100644
--- a/testing/test_unit.py
+++ b/testing/test_unit.py
@@ -5,6 +5,8 @@
import pytest
from assertpy import assert_that
+from pytest_html.basereport import BaseReport
+
pytest_plugins = ("pytester",)
@@ -146,3 +148,24 @@ def test_custom_css_selfcontained(pytester, css_file_path, expandvar):
with open(pytester.path / "report.html") as f:
html = f.read()
assert_that(html).contains("* " + str(css_file_path)).contains("* two.css")
+
+
+def test_asset_filename_accounts_for_assets_directory_prefix():
+ """Relative asset paths must stay within max_asset_filename_length (#906)."""
+
+ class _Report:
+ _max_asset_filename_length = 255
+ _assets_path = Path("report_dir") / "assets"
+
+ filename = BaseReport._asset_filename(
+ _Report(),
+ "test_" + "a" * 300,
+ extra_index=0,
+ test_index=0,
+ file_extension="png",
+ )
+ relative_path = str(Path("assets") / filename).replace("\\", "/")
+ assert_that(len(filename)).is_less_than_or_equal_to(255 - len("assets/"))
+ assert_that(len(relative_path)).is_less_than_or_equal_to(255)
+ assert_that(relative_path).starts_with("assets/")
+ assert_that(filename).ends_with(".png")