diff --git a/src/tmt_web/templates/_base.html.j2 b/src/tmt_web/templates/_base.html.j2 index 1b647ef..7fdc9e1 100644 --- a/src/tmt_web/templates/_base.html.j2 +++ b/src/tmt_web/templates/_base.html.j2 @@ -155,6 +155,27 @@ licensed under CC-BY-SA 4.0 (https://creativecommons.org/licenses/by-sa/4.0/). color: var(--fedora-dark); font-weight: 600; } + + .description { + margin: 0.75rem 0; + } + + .description p { + margin-bottom: 0.5rem; + } + + .description-text { + background: white; + padding: 1rem; + border-radius: 4px; + border-left: 4px solid var(--fedora-blue); + margin: 0; + font-family: 'Courier New', 'Monaco', 'Menlo', monospace; + font-size: 0.9rem; + white-space: pre-wrap; + word-wrap: break-word; + overflow-x: auto; + } {% block head %}{% endblock %} diff --git a/src/tmt_web/templates/testandplan.html.j2 b/src/tmt_web/templates/testandplan.html.j2 index 51a9c22..33448be 100644 --- a/src/tmt_web/templates/testandplan.html.j2 +++ b/src/tmt_web/templates/testandplan.html.j2 @@ -12,7 +12,10 @@

Summary: {{ test.summary }}

{% endif %} {% if test.description %} -

Description: {{ test.description }}

+
+

Description:

+
{{ test.description }}
+
{% endif %} {% if test.tier %}

Tier: {{ test.tier }}

@@ -66,7 +69,10 @@

Summary: {{ plan.summary }}

{% endif %} {% if plan.description %} -

Description: {{ plan.description }}

+
+

Description:

+
{{ plan.description }}
+
{% endif %} {% if plan.tier %}

Tier: {{ plan.tier }}

diff --git a/src/tmt_web/templates/testorplan.html.j2 b/src/tmt_web/templates/testorplan.html.j2 index cd3e5c5..dc66b04 100644 --- a/src/tmt_web/templates/testorplan.html.j2 +++ b/src/tmt_web/templates/testorplan.html.j2 @@ -11,7 +11,10 @@

Summary: {{ testorplan.summary }}

{% endif %} {% if testorplan.description %} -

Description: {{ testorplan.description }}

+
+

Description:

+
{{ testorplan.description }}
+
{% endif %} {% if testorplan.tier %}

Tier: {{ testorplan.tier }}

diff --git a/tests/unit/test_html_generator.py b/tests/unit/test_html_generator.py index 539ec09..9c7f089 100644 --- a/tests/unit/test_html_generator.py +++ b/tests/unit/test_html_generator.py @@ -223,3 +223,47 @@ def mock_render(*args, **kwargs): html_generator._render_template("testorplan.html.j2", logger) assert "Failed to render template" in str(exc.value) assert "testorplan.html.j2" in str(exc.value) + + def test_multiline_description_rendering(self, logger): + """Test that multiline descriptions are rendered correctly with line breaks preserved.""" + # Create test data with multiline description + multiline_description = ( + "First line of description\n\nSecond line after empty line\nThird line\n\nFourth line" + ) + test_data = TestData( + name="multiline-test", + summary="Test with multiline description", + description=multiline_description, + contact=["Test Contact "], + component=["component1"], + enabled=True, + environment={"KEY": "value"}, + duration="15m", + framework="shell", + manual=False, + path="/path/to/test", + tier="1", + order=50, + id="test-multiline", + tag=["tag1"], + fmf_id=FmfIdData( + name="test", + url="https://example.com/test", + path="/path/to/test", + ref="main", + ), + ) + + data = html_generator.generate_html_page(test_data, logger) + + # Check that the description is wrapped in proper HTML structure + assert '
' in data + assert '
' in data
+        assert "
" in data + assert "
" in data + + # Check that the multiline content is preserved + assert "First line of description" in data + assert "Second line after empty line" in data + assert "Third line" in data + assert "Fourth line" in data