From 467b57fb34010fd41ce1551eddd5bca84a747add Mon Sep 17 00:00:00 2001 From: Bangarraju-Microsoft Date: Wed, 18 Jun 2025 16:42:06 +0530 Subject: [PATCH 1/6] GP Test automation - removed duplicate entries. --- .../tests/test_contentProcessing_gp_tc.py | 68 +++++++++++++------ 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/tests/e2e-test/tests/test_contentProcessing_gp_tc.py b/tests/e2e-test/tests/test_contentProcessing_gp_tc.py index d831cd43..66dead64 100644 --- a/tests/e2e-test/tests/test_contentProcessing_gp_tc.py +++ b/tests/e2e-test/tests/test_contentProcessing_gp_tc.py @@ -1,28 +1,49 @@ import logging +import time 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")), + ("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()), + ("Refreshing the page until the 'Invoice' file 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()) + ( + "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"), + ), + ("Refreshing the page until the 'Claim Form' 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 user able to delete file", 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)] +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) @@ -30,17 +51,26 @@ def test_content_processing_steps(login_logout, description, action, request): """ Executes Golden Path content processing steps with individual log entries. """ - request.node._nodeid = description page = login_logout home = HomePage(page) - + logger.info(f"Running test step: {description}") + + start_time = time.time() + try: action(home) + duration = time.time() - start_time + logger.info(f"Step passed: {description} (Duration: {duration:.2f} seconds)") + request.node._report_sections.append( + ("call", "log", f"Step passed: {description} (Duration: {duration:.2f} seconds)") + ) except Exception as e: - logger.error(f"Step failed: {description}") + duration = time.time() - start_time + logger.error(f"Step failed: {description} (Duration: {duration:.2f} seconds)") raise - - # Optionally attach to report + + request.node._nodeid = description + request.node._report_sections.append(("call", "log", f"Step passed: {description}")) From f3a394cf39352d2445744c503057f8696a2ecd08 Mon Sep 17 00:00:00 2001 From: Bangarraju-Microsoft Date: Wed, 18 Jun 2025 17:59:00 +0530 Subject: [PATCH 2/6] pylint error resolved --- tests/e2e-test/tests/test_contentProcessing_gp_tc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e-test/tests/test_contentProcessing_gp_tc.py b/tests/e2e-test/tests/test_contentProcessing_gp_tc.py index 66dead64..307d0629 100644 --- a/tests/e2e-test/tests/test_contentProcessing_gp_tc.py +++ b/tests/e2e-test/tests/test_contentProcessing_gp_tc.py @@ -66,7 +66,7 @@ def test_content_processing_steps(login_logout, description, action, request): request.node._report_sections.append( ("call", "log", f"Step passed: {description} (Duration: {duration:.2f} seconds)") ) - except Exception as e: + except Exception: duration = time.time() - start_time logger.error(f"Step failed: {description} (Duration: {duration:.2f} seconds)") raise From 639f16a1a391a9429a6ec0bdf1bfdde0cb9517da Mon Sep 17 00:00:00 2001 From: Bangarraju-Microsoft Date: Wed, 18 Jun 2025 18:32:07 +0530 Subject: [PATCH 3/6] linting issues --- tests/e2e-test/tests/conftest.py | 91 ++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 35 deletions(-) diff --git a/tests/e2e-test/tests/conftest.py b/tests/e2e-test/tests/conftest.py index e43ff21d..ab65ca98 100644 --- a/tests/e2e-test/tests/conftest.py +++ b/tests/e2e-test/tests/conftest.py @@ -1,37 +1,52 @@ +""" +Pytest configuration for browser-based testing with Playwright and HTML report customization. +""" + import os -import atexit import io -from bs4 import BeautifulSoup -import pytest +import atexit import logging -from config.constants import URL +from pathlib import Path + +import pytest +from bs4 import BeautifulSoup from playwright.sync_api import sync_playwright +from config.constants import URL + +# Global dictionary to store log streams for each test +LOG_STREAMS = {} + @pytest.fixture(scope="session") def login_logout(): - # perform login and browser close once in a session - with sync_playwright() as p: - browser = p.chromium.launch(headless=False, args=["--start-maximized"]) + """ + Fixture to launch the browser, log in, and yield the page object. + Closes the browser after the session ends. + """ + with sync_playwright() as playwright: + browser = playwright.chromium.launch(headless=False, args=["--start-maximized"]) context = browser.new_context(no_viewport=True) context.set_default_timeout(80000) page = context.new_page() - # Navigate to the login URL + page.goto(URL, wait_until="domcontentloaded") - # login to web url with username and password + + # Uncomment and complete the following to enable login # login_page = LoginPage(page) # load_dotenv() - # login_page.authenticate(os.getenv('user_name'), os.getenv('pass_word')) + # login_page.authenticate(os.getenv("user_name"), os.getenv("pass_word")) yield page - # perform close the browser + browser.close() -log_streams = {} @pytest.hookimpl(tryfirst=True) def pytest_runtest_setup(item): - # Prepare StringIO for capturing logs + """ + Pytest hook to set up a log capture for each test. + """ stream = io.StringIO() handler = logging.StreamHandler(stream) handler.setLevel(logging.INFO) @@ -39,62 +54,68 @@ def pytest_runtest_setup(item): logger = logging.getLogger() logger.addHandler(handler) - # Save handler and stream - log_streams[item.nodeid] = (handler, stream) + LOG_STREAMS[item.nodeid] = (handler, stream) @pytest.hookimpl(hookwrapper=True) def pytest_runtest_makereport(item, call): + """ + Pytest hook to add captured logs to the test report. + """ outcome = yield report = outcome.get_result() - handler, stream = log_streams.get(item.nodeid, (None, None)) + 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) + LOG_STREAMS.pop(item.nodeid, None) else: report.description = "" + def pytest_collection_modifyitems(items): + """ + Modify test node IDs based on the test's parameterized 'prompt' value. + """ for item in items: - if hasattr(item, 'callspec'): + 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 + item._nodeid = prompt + def rename_duration_column(): - report_path = os.path.abspath("report.html") # or your report filename - if not os.path.exists(report_path): + """ + Modify the HTML report to rename 'Duration' column to 'Execution Time'. + Runs automatically after the test session. + """ + report_path = Path("report.html") + if not report_path.exists(): print("Report file not found, skipping column rename.") return - with open(report_path, 'r', encoding='utf-8') as f: - soup = BeautifulSoup(f, 'html.parser') + with report_path.open("r", encoding="utf-8") as file: + soup = BeautifulSoup(file, "html.parser") - # Find and rename the header - headers = soup.select('table#results-table thead th') + 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'") + if th.text.strip() == "Duration": + th.string = "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)) + with report_path.open("w", encoding="utf-8") as file: + file.write(str(soup)) + -# Register this function to run after everything is done +# Register HTML report column modification atexit.register(rename_duration_column) From 47db719dc74b2d7be9964d117a645985a22f4167 Mon Sep 17 00:00:00 2001 From: Bangarraju-Microsoft Date: Thu, 19 Jun 2025 12:48:16 +0530 Subject: [PATCH 4/6] resolved comments --- tests/e2e-test/tests/conftest.py | 3 ++- .../tests/test_contentProcessing_gp_tc.py | 16 ++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/e2e-test/tests/conftest.py b/tests/e2e-test/tests/conftest.py index ab65ca98..d57e34bb 100644 --- a/tests/e2e-test/tests/conftest.py +++ b/tests/e2e-test/tests/conftest.py @@ -7,6 +7,7 @@ import atexit import logging from pathlib import Path +from venv import logger import pytest from bs4 import BeautifulSoup @@ -99,7 +100,7 @@ def rename_duration_column(): """ report_path = Path("report.html") if not report_path.exists(): - print("Report file not found, skipping column rename.") + logger.info("Report file not found, skipping column rename.") return with report_path.open("r", encoding="utf-8") as file: diff --git a/tests/e2e-test/tests/test_contentProcessing_gp_tc.py b/tests/e2e-test/tests/test_contentProcessing_gp_tc.py index 307d0629..44823f5a 100644 --- a/tests/e2e-test/tests/test_contentProcessing_gp_tc.py +++ b/tests/e2e-test/tests/test_contentProcessing_gp_tc.py @@ -51,7 +51,8 @@ def test_content_processing_steps(login_logout, description, action, request): """ Executes Golden Path content processing steps with individual log entries. """ - + request.node._nodeid = description + page = login_logout home = HomePage(page) @@ -62,15 +63,14 @@ def test_content_processing_steps(login_logout, description, action, request): try: action(home) duration = time.time() - start_time - logger.info(f"Step passed: {description} (Duration: {duration:.2f} seconds)") - request.node._report_sections.append( - ("call", "log", f"Step passed: {description} (Duration: {duration:.2f} seconds)") - ) + message = "Step passed: %s (Duration: %.2f seconds)" % (description, duration) + logger.info(message) + request.node._report_sections.append(("call", "log", message)) + except Exception: duration = time.time() - start_time - logger.error(f"Step failed: {description} (Duration: {duration:.2f} seconds)") + logger.error("Step failed: %s (Duration: %.2f seconds)", description, duration, exc_info=True) raise - request.node._nodeid = description - + request.node._report_sections.append(("call", "log", f"Step passed: {description}")) From ab7c81b8bf3919645bf846852bbd6af2a394b148 Mon Sep 17 00:00:00 2001 From: Bangarraju-Microsoft Date: Thu, 19 Jun 2025 12:54:11 +0530 Subject: [PATCH 5/6] lint issues --- tests/e2e-test/tests/conftest.py | 1 - tests/e2e-test/tests/test_contentProcessing_gp_tc.py | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/e2e-test/tests/conftest.py b/tests/e2e-test/tests/conftest.py index d57e34bb..a6459bf2 100644 --- a/tests/e2e-test/tests/conftest.py +++ b/tests/e2e-test/tests/conftest.py @@ -2,7 +2,6 @@ Pytest configuration for browser-based testing with Playwright and HTML report customization. """ -import os import io import atexit import logging diff --git a/tests/e2e-test/tests/test_contentProcessing_gp_tc.py b/tests/e2e-test/tests/test_contentProcessing_gp_tc.py index 44823f5a..466afc2f 100644 --- a/tests/e2e-test/tests/test_contentProcessing_gp_tc.py +++ b/tests/e2e-test/tests/test_contentProcessing_gp_tc.py @@ -52,14 +52,12 @@ def test_content_processing_steps(login_logout, description, action, request): Executes Golden Path content processing steps with individual log entries. """ request.node._nodeid = description - page = login_logout home = HomePage(page) logger.info(f"Running test step: {description}") start_time = time.time() - try: action(home) duration = time.time() - start_time @@ -71,6 +69,5 @@ def test_content_processing_steps(login_logout, description, action, request): duration = time.time() - start_time logger.error("Step failed: %s (Duration: %.2f seconds)", description, duration, exc_info=True) raise - - + request.node._report_sections.append(("call", "log", f"Step passed: {description}")) From dc527125bbaaaf5d5c512aa34acd7c4bdb3c3ff2 Mon Sep 17 00:00:00 2001 From: Bangarraju-Microsoft Date: Thu, 19 Jun 2025 12:59:41 +0530 Subject: [PATCH 6/6] Pylint issue --- tests/e2e-test/tests/test_contentProcessing_gp_tc.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/e2e-test/tests/test_contentProcessing_gp_tc.py b/tests/e2e-test/tests/test_contentProcessing_gp_tc.py index 466afc2f..7fe90c2c 100644 --- a/tests/e2e-test/tests/test_contentProcessing_gp_tc.py +++ b/tests/e2e-test/tests/test_contentProcessing_gp_tc.py @@ -69,5 +69,4 @@ def test_content_processing_steps(login_logout, description, action, request): duration = time.time() - start_time logger.error("Step failed: %s (Duration: %.2f seconds)", description, duration, exc_info=True) raise - request.node._report_sections.append(("call", "log", f"Step passed: {description}"))