diff --git a/tests/e2e-test/pytest.ini b/tests/e2e-test/pytest.ini index 76eb64fc..05b7f91c 100644 --- a/tests/e2e-test/pytest.ini +++ b/tests/e2e-test/pytest.ini @@ -3,4 +3,5 @@ log_cli = true log_cli_level = INFO log_file = logs/tests.log log_file_level = INFO -addopts = -p no:warnings +addopts = -p no:warnings --tb=short + diff --git a/tests/e2e-test/readme.MD b/tests/e2e-test/readme.MD index 941d3653..13d4aa47 100644 --- a/tests/e2e-test/readme.MD +++ b/tests/e2e-test/readme.MD @@ -24,7 +24,7 @@ Installing Playwright Pytest from Virtual Environment Run test cases -- To run test cases from your 'tests' folder : "pytest --html=report.html --self-contained-html" +- To run test cases from your 'tests/e2e-test' folder : "pytest --html=report.html --self-contained-html" Create .env file in project root level with web app url and client credentials diff --git a/tests/e2e-test/requirements.txt b/tests/e2e-test/requirements.txt index 7aad0cfb..4e488e55 100644 --- a/tests/e2e-test/requirements.txt +++ b/tests/e2e-test/requirements.txt @@ -3,4 +3,5 @@ pytest-reporter-html1 python-dotenv pytest-check pytest-html -py \ No newline at end of file +py +beautifulsoup4 \ No newline at end of file diff --git a/tests/e2e-test/tests/conftest.py b/tests/e2e-test/tests/conftest.py index d356dc40..e43ff21d 100644 --- a/tests/e2e-test/tests/conftest.py +++ b/tests/e2e-test/tests/conftest.py @@ -1,9 +1,11 @@ import os - +import atexit +import io +from bs4 import BeautifulSoup import pytest +import logging from config.constants import URL from playwright.sync_api import sync_playwright -from py.xml import html # type: ignore @pytest.fixture(scope="session") @@ -25,29 +27,74 @@ def login_logout(): # perform close the browser browser.close() +log_streams = {} @pytest.hookimpl(tryfirst=True) -def pytest_html_report_title(report): - report.title = "Automation_Content_Processing" - +def pytest_runtest_setup(item): + # Prepare StringIO for capturing logs + stream = io.StringIO() + handler = logging.StreamHandler(stream) + handler.setLevel(logging.INFO) -# Add a column for descriptions -def pytest_html_results_table_header(cells): - cells.insert(1, html.th("Description")) + logger = logging.getLogger() + logger.addHandler(handler) + # Save handler and stream + log_streams[item.nodeid] = (handler, stream) -def pytest_html_results_table_row(report, cells): - cells.insert( - 1, html.td(report.description if hasattr(report, "description") else "") - ) - -# Add logs and docstring to report @pytest.hookimpl(hookwrapper=True) def pytest_runtest_makereport(item, call): outcome = yield report = outcome.get_result() - report.description = str(item.function.__doc__) - os.makedirs("logs", exist_ok=True) - extra = getattr(report, "extra", []) - report.extra = extra + + handler, stream = log_streams.get(item.nodeid, (None, None)) + + if handler and stream: + # Make sure logs are flushed + handler.flush() + log_output = stream.getvalue() + + # Only remove the handler, don't close the stream yet + logger = logging.getLogger() + logger.removeHandler(handler) + + # Store the log output on the report object for HTML reporting + report.description = f"
{log_output.strip()}"
+
+ # Clean up references
+ log_streams.pop(item.nodeid, None)
+ else:
+ report.description = ""
+
+def pytest_collection_modifyitems(items):
+ for item in items:
+ if hasattr(item, 'callspec'):
+ prompt = item.callspec.params.get("prompt")
+ if prompt:
+ item._nodeid = prompt # This controls how the test name appears in the report
+
+def rename_duration_column():
+ report_path = os.path.abspath("report.html") # or your report filename
+ if not os.path.exists(report_path):
+ print("Report file not found, skipping column rename.")
+ return
+
+ with open(report_path, 'r', encoding='utf-8') as f:
+ soup = BeautifulSoup(f, 'html.parser')
+
+ # Find and rename the header
+ headers = soup.select('table#results-table thead th')
+ for th in headers:
+ if th.text.strip() == 'Duration':
+ th.string = 'Execution Time'
+ #print("Renamed 'Duration' to 'Execution Time'")
+ break
+ else:
+ print("'Duration' column not found in report.")
+
+ with open(report_path, 'w', encoding='utf-8') as f:
+ f.write(str(soup))
+
+# Register this function to run after everything is done
+atexit.register(rename_duration_column)
diff --git a/tests/e2e-test/tests/test_contentProcessing_gp_tc.py b/tests/e2e-test/tests/test_contentProcessing_gp_tc.py
index cbe99797..d831cd43 100644
--- a/tests/e2e-test/tests/test_contentProcessing_gp_tc.py
+++ b/tests/e2e-test/tests/test_contentProcessing_gp_tc.py
@@ -1,41 +1,46 @@
import logging
-
import pytest
from pages.HomePage import HomePage
-
+
logger = logging.getLogger(__name__)
+
+# Define step-wise test actions for Golden Path
+golden_path_steps = [
+ ("Validate home page is loaded", lambda home: home.validate_home_page()),
+ ("Select Invoice Schema", lambda home: home.select_schema("Invoice")),
+ ("Upload Invoice documents", lambda home: home.upload_files("Invoice")),
+ ("Refresh page till status is updated to Completed", lambda home: home.refresh()),
+ ("Validate extracted result for Invoice", lambda home: home.validate_invoice_extracted_result()),
+ ("Modify Extracted Data JSON & submit comments", lambda home: home.modify_and_submit_extracted_data()),
+ ("Validate process steps for Invoice", lambda home: home.validate_process_steps()),
+ ("Select Property Loss Damage Claim Form Schema", lambda home: home.select_schema("Property")),
+ ("Upload Property Loss Damage Claim Form documents", lambda home: home.upload_files("Property")),
+ ("Refresh page till status is updated to Completed", lambda home: home.refresh()),
+ ("Validate extracted result for Property Loss Damage Claim Form", lambda home: home.validate_property_extracted_result()),
+ ("Validate process steps for Property Loss Damage Claim Form", lambda home: home.validate_process_steps()),
+ ("Validate Delete files", lambda home: home.delete_files())
+]
+
+# Generate readable test step IDs
+golden_path_ids = [f"{i+1:02d}. {desc}" for i, (desc, _) in enumerate(golden_path_steps)]
+
+@pytest.mark.parametrize("description, action", golden_path_steps, ids=golden_path_ids)
+def test_content_processing_steps(login_logout, description, action, request):
+ """
+ Executes Golden Path content processing steps with individual log entries.
+ """
+ request.node._nodeid = description
-@pytest.mark.testcase_id("TC001")
-def test_ContentProcessing_Golden_path_test(login_logout):
- """Validate Golden path test case for Content Processing Accelerator"""
page = login_logout
- home_page = HomePage(page)
- logger.info("Step 1: Validate home page is loaded.")
- home_page.validate_home_page()
- logger.info("Step 2: Select Invoice Schema.")
- home_page.select_schema("Invoice")
- logger.info("Step 3: Upload Invoice documents.")
- home_page.upload_files("Invoice")
- logger.info("Step 4: Refresh page till status is updated to Completed.")
- home_page.refresh()
- logger.info("Step 5: Validate extracted result for Invoice.")
- home_page.validate_invoice_extracted_result()
- logger.info("Step 6: Modify Extracted Data JSON & submit comments.")
- home_page.modify_and_submit_extracted_data()
- logger.info("Step 7: Validate process steps for Invoice")
- home_page.validate_process_steps()
- logger.info("Step 8: Select Property Loss Damage Claim Form Schema.")
- home_page.select_schema("Property")
- logger.info("Step 9: Upload Property Loss Damage Claim Form documents.")
- home_page.upload_files("Property")
- logger.info("Step 10: Refresh page till status is updated to Completed.")
- home_page.refresh()
- logger.info(
- "Step 11: Validate extracted result for Property Loss Damage Claim Form."
- )
- home_page.validate_property_extracted_result()
- logger.info("Step 12: Validate process steps for Property Loss Damage Claim Form.")
- home_page.validate_process_steps()
- logger.info("Step 13: Validate Delete files.")
- home_page.delete_files()
+ home = HomePage(page)
+
+ logger.info(f"Running test step: {description}")
+ try:
+ action(home)
+ except Exception as e:
+ logger.error(f"Step failed: {description}")
+ raise
+
+ # Optionally attach to report
+ request.node._report_sections.append(("call", "log", f"Step passed: {description}"))