From 5c5cdf38b1d60405a4a33eea1569720e282ac215 Mon Sep 17 00:00:00 2001 From: Emjey Date: Wed, 10 Jun 2026 03:39:19 +0000 Subject: [PATCH 1/6] Add support for search tests by error logs --- Makefile | 4 ++-- pytest_html_plus/generate_html_report.py | 16 ++++++++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 696be00..2be5042 100644 --- a/Makefile +++ b/Makefile @@ -22,10 +22,10 @@ shell: $(IMAGE_NAME) /bin/bash test: - poetry run pytest tests/unit --reruns 1 + $(DOCKER_RUN) poetry run pytest tests/unit --reruns 1 test-with-xdist: - poetry run pytest tests/unit --reruns 1 -n auto + $(DOCKER_RUN) poetry run pytest tests/unit --reruns 1 -n auto lint: $(DOCKER_RUN) poetry run ruff check . diff --git a/pytest_html_plus/generate_html_report.py b/pytest_html_plus/generate_html_report.py index 677d1fb..01ef786 100644 --- a/pytest_html_plus/generate_html_report.py +++ b/pytest_html_plus/generate_html_report.py @@ -4,7 +4,7 @@ import os import shutil from datetime import datetime, timezone - +from html import escape from pytest_html_plus.compute_filter_counts import compute_filter_count from pytest_html_plus.utils import extract_error_block, extract_trace_block @@ -614,7 +614,8 @@ def generate_html_report(self): document.querySelectorAll('.test-card').forEach(card => {{ const name = card.getAttribute('data-name') || ''; const link = card.getAttribute('data-link') || ''; - const isVisible = name.toLowerCase().includes(filter) || link.toLowerCase().includes(filter); + const error = card.getAttribute('data-error') || ''; + const isVisible = name.toLowerCase().includes(filter) || link.toLowerCase().includes(filter) || error.toLowerCase().includes(filter); card.style.display = isVisible ? '' : 'none'; }}); }}); @@ -750,7 +751,7 @@ def generate_html_report(self): @@ -873,6 +874,8 @@ def generate_html_report(self): """ attempts_html += "" + + search_error = "" if test.get("error"): full_error = test["error"] @@ -891,6 +894,11 @@ def generate_html_report(self):
Error: {self.generate_copy_button(error_content, "error")}
{error_content}
""" + search_error = ( + error_content.replace("\n", " ") + .replace("\r", " ") + )[:1000] + flaky_badge = "" if test.get("flaky"): @@ -928,7 +936,7 @@ def generate_html_report(self): ) html += f""" -
+
From a3895450ad741a9e2ca3757343f3e6a711bc96d3 Mon Sep 17 00:00:00 2001 From: Emjey Date: Wed, 10 Jun 2026 10:07:47 +0000 Subject: [PATCH 2/6] Update gif --- README.md | 14 ++++++++------ docs/Features/search.rst | 29 ++++++++++++++++++----------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index ae2f338..3520e59 100644 --- a/README.md +++ b/README.md @@ -96,19 +96,21 @@ No need for custom marker definitions. Perfect for smarter filtering, reporting, ![ScreenRecording2025-06-29at1 06 02AM-ezgif com-video-to-gif-converter](https://github.com/user-attachments/assets/af40622f-f548-44a5-982b-344c74a65e13) -#### 🔍 Universal Test Search + Smart Link Navigation +#### 🔍 Universal Test Search + Smart Traceability -Whether you're trying to trace coverage or track unlinked test cases — this search has your back! +Whether you're tracing coverage, investigating failures, or tracking unlinked test cases — this search has your back! Just start typing, and the dashboard will instantly filter tests by: -✅ Test name +✅ Test names -✅ Linked issue/documentation IDs (like JIRA, Testmo, Notion, etc.) +✅ Linked issue or documentation IDs (JIRA, Testmo, Notion, etc.) + +✅ Custom URLs or keywords present in linked references + +✅ Error messages and trace snippets to quickly group related failures -✅ Custom URLs or keywords present in the links -![ScreenRecording2025-06-21at3 10 06PM-ezgif com-video-to-gif-converter](https://github.com/user-attachments/assets/f81c9a81-f98d-4151-ad7a-c1184cd199eb) #### 📸 Screenshot Support: View screenshots directly in the report to understand failures faster. diff --git a/docs/Features/search.rst b/docs/Features/search.rst index 0320246..4827b3a 100644 --- a/docs/Features/search.rst +++ b/docs/Features/search.rst @@ -1,21 +1,28 @@ -Universal Test Search + Smart Link Navigation -============================================= +# Universal Test Search + Smart Traceability -The `pytest-html-plus` report comes with a powerful search bar at the top of the page, helping you find the test cases you care about in real-time. +The `pytest-html-plus` report includes a powerful search bar that instantly filters tests as you type, helping you quickly locate failures, trace coverage, and navigate linked references. -Search and Navigate: ---------------------- +## Search and Navigate -Just start typing, and the dashboard will instantly filter and display tests based on: +Simply start typing, and the dashboard will filter tests in real time based on: -✅ **Test name** +✅ **Test names** -✅ **Linked external IDs** — such as JIRA, Testmo, Notion, or any quoted references you attach (e.g. `JIRA-123`, `DOC-456`, etc.) +✅ **Linked external IDs** — such as JIRA, Testmo, Notion, or any quoted references you attach (for example `JIRA-123`, `DOC-456`, etc.) -✅ **Custom URLs or keywords** — any meaningful text or link in the associated references will be indexed. +✅ **Custom URLs or keywords** — any meaningful text or link in associated references will be indexed + +✅ **Error messages and trace snippets** — quickly find tests sharing similar failures, assertion messages, or exception types .. tip:: - This smart search helps you **trace coverage**, **group tests by external references**, or **isolate unlinked cases** with ease. -For example, if you tag tests with a JIRA ID or Notion doc, typing that ID in the search bar will instantly filter all associated test cases for traceability. +This smart search helps you **trace coverage**, **group tests by external references**, and **identify related failures** with ease. + +## Examples + +* Search `JIRA-123` to display all tests linked to that issue. +* Search `TimeoutError` to locate tests failing due to timeouts. +* Search `NoSuchElementException` to identify Selenium or Playwright locator failures. +* Search `expected 200` to find API assertions with matching error messages. +This makes it easy to investigate patterns, correlate failures, and navigate large reports efficiently. From 122f9fed6707fe1cfa46d4b703c7c841931a6805 Mon Sep 17 00:00:00 2001 From: Emjey Date: Wed, 10 Jun 2026 15:38:58 +0530 Subject: [PATCH 3/6] Add screenshot support section to README Added a section for screenshot support in the README. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3520e59..7ef7c19 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,7 @@ Just start typing, and the dashboard will instantly filter tests by: ✅ Error messages and trace snippets to quickly group related failures +new_search #### 📸 Screenshot Support: View screenshots directly in the report to understand failures faster. From 08b98f2d167a00e2b8ce37ecc5e2f8db42ae2c1e Mon Sep 17 00:00:00 2001 From: Emjey Date: Wed, 10 Jun 2026 11:44:41 +0000 Subject: [PATCH 4/6] Update version --- .gitignore | 1 - pyproject.toml | 3 ++- tests/unit/test_error_block.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 588c8ba..3047e59 100644 --- a/.gitignore +++ b/.gitignore @@ -67,7 +67,6 @@ instance/ # Scrapy stuff: .scrapy -.git # Sphinx documentation docs/_build/ diff --git a/pyproject.toml b/pyproject.toml index cfb9477..ecfbfc3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pytest-html-plus" -version = "1.0.1" +version = "1.1.0" description = "Generate Actionable, automatic screenshots, unified Mobile friendly Pytest HTML report in less than 3 seconds — no hooks, merge plugins, no config, xdist-ready." readme = "README.md" authors = ["reporterplus"] @@ -85,6 +85,7 @@ ignore = [ ] exclude = [ "pytest_html_plus/generate_html_report.py" + ".git" ] [tool.ruff.lint] diff --git a/tests/unit/test_error_block.py b/tests/unit/test_error_block.py index 25272e1..a619e1f 100644 --- a/tests/unit/test_error_block.py +++ b/tests/unit/test_error_block.py @@ -1,18 +1,18 @@ from pytest_html_plus.utils import extract_error_block - +import pytest def test_error_block_basic(): error = "line 1\nE AssertionError: something went wrong\nline 3\nE ValueError: another error" # noqa expected = "E AssertionError: something went wrong\nE ValueError: another error" assert extract_error_block(error) == expected - +@pytest.mark.jira("https://acme.atlassian.net/browse/QA-123") def test_error_block_spaces_and_blank_lines(): error = "\n\n E TypeError\n\n \nE IndexError\n" expected = "E TypeError\nE IndexError" assert extract_error_block(error) == expected - +@pytest.mark.link("https://acme.atlassian.net/browse/PAY-456") def test_error_block_no_E_lines(): error = "line 1\nline 2" expected = "line 1\nline 2" From 4b3b44c0a7178e9f56089935503b41463b74b1da Mon Sep 17 00:00:00 2001 From: Emjey Date: Wed, 10 Jun 2026 11:47:57 +0000 Subject: [PATCH 5/6] update toml syntax fix --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ecfbfc3..ce98ace 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -84,7 +84,7 @@ ignore = [ "W293", # blank line whitespace — let black handle ] exclude = [ - "pytest_html_plus/generate_html_report.py" + "pytest_html_plus/generate_html_report.py", ".git" ] From 215ed910cfa862dcde54a6cb4686ec94242673ca Mon Sep 17 00:00:00 2001 From: Emjey Date: Wed, 10 Jun 2026 11:53:16 +0000 Subject: [PATCH 6/6] fix lint errors --- tests/unit/test_error_block.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/unit/test_error_block.py b/tests/unit/test_error_block.py index a619e1f..ec0cd04 100644 --- a/tests/unit/test_error_block.py +++ b/tests/unit/test_error_block.py @@ -1,17 +1,21 @@ -from pytest_html_plus.utils import extract_error_block import pytest +from pytest_html_plus.utils import extract_error_block + + def test_error_block_basic(): error = "line 1\nE AssertionError: something went wrong\nline 3\nE ValueError: another error" # noqa expected = "E AssertionError: something went wrong\nE ValueError: another error" assert extract_error_block(error) == expected + @pytest.mark.jira("https://acme.atlassian.net/browse/QA-123") def test_error_block_spaces_and_blank_lines(): error = "\n\n E TypeError\n\n \nE IndexError\n" expected = "E TypeError\nE IndexError" assert extract_error_block(error) == expected + @pytest.mark.link("https://acme.atlassian.net/browse/PAY-456") def test_error_block_no_E_lines(): error = "line 1\nline 2"