Skip to content

Commit e4fa30a

Browse files
GP Test automation changes
1 parent 4c4da02 commit e4fa30a

5 files changed

Lines changed: 119 additions & 36 deletions

File tree

tests/e2e-test/pytest.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ log_cli = true
33
log_cli_level = INFO
44
log_file = logs/tests.log
55
log_file_level = INFO
6-
addopts = -p no:warnings
6+
addopts = -p no:warnings --tb=short

tests/e2e-test/readme.MD

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Installing Playwright Pytest from Virtual Environment
2424

2525
Run test cases
2626

27-
- To run test cases from your 'tests' folder : "pytest --html=report.html --self-contained-html"
27+
- To run test cases from your 'tests/e2e-test' folder : "pytest --html=report.html --self-contained-html"
2828

2929
Create .env file in project root level with web app url and client credentials
3030

tests/e2e-test/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ python-dotenv
44
pytest-check
55
pytest-html
66
py
7+
beautifulsoup4

tests/e2e-test/tests/conftest.py

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import os
2-
2+
import atexit
3+
import io
4+
from bs4 import BeautifulSoup
5+
import pytest
6+
import logging
37
from config.constants import URL
4-
58
from playwright.sync_api import sync_playwright
6-
79
from py.xml import html # type: ignore
810

9-
import pytest
10-
11-
1211
@pytest.fixture(scope="session")
1312
def login_logout():
1413
# perform login and browser close once in a session
@@ -31,15 +30,87 @@ def pytest_html_report_title(report):
3130

3231

3332
# Add a column for descriptions
34-
def pytest_html_results_table_header(cells):
35-
cells.insert(1, html.th("Description"))
33+
# def pytest_html_results_table_header(cells):
34+
# cells.insert(1, html.th("Description"))
35+
36+
37+
# def pytest_html_results_table_row(report, cells):
38+
# cells.insert(
39+
# 1, html.td(report.description if hasattr(report, "description") else "")
40+
# )
41+
42+
43+
log_streams = {}
44+
45+
@pytest.hookimpl(tryfirst=True)
46+
def pytest_runtest_setup(item):
47+
# Prepare StringIO for capturing logs
48+
stream = io.StringIO()
49+
handler = logging.StreamHandler(stream)
50+
handler.setLevel(logging.INFO)
51+
52+
logger = logging.getLogger()
53+
logger.addHandler(handler)
54+
55+
# Save handler and stream
56+
log_streams[item.nodeid] = (handler, stream)
57+
58+
59+
@pytest.hookimpl(hookwrapper=True)
60+
def pytest_runtest_makereport(item, call):
61+
outcome = yield
62+
report = outcome.get_result()
63+
64+
handler, stream = log_streams.get(item.nodeid, (None, None))
65+
66+
if handler and stream:
67+
# Make sure logs are flushed
68+
handler.flush()
69+
log_output = stream.getvalue()
70+
71+
# Only remove the handler, don't close the stream yet
72+
logger = logging.getLogger()
73+
logger.removeHandler(handler)
74+
75+
# Store the log output on the report object for HTML reporting
76+
report.description = f"<pre>{log_output.strip()}</pre>"
77+
78+
# Clean up references
79+
log_streams.pop(item.nodeid, None)
80+
else:
81+
report.description = ""
82+
83+
def pytest_collection_modifyitems(items):
84+
for item in items:
85+
if hasattr(item, 'callspec'):
86+
prompt = item.callspec.params.get("prompt")
87+
if prompt:
88+
item._nodeid = prompt # This controls how the test name appears in the report
89+
90+
def rename_duration_column():
91+
report_path = os.path.abspath("report.html") # or your report filename
92+
if not os.path.exists(report_path):
93+
print("Report file not found, skipping column rename.")
94+
return
95+
96+
with open(report_path, 'r', encoding='utf-8') as f:
97+
soup = BeautifulSoup(f, 'html.parser')
3698

99+
# Find and rename the header
100+
headers = soup.select('table#results-table thead th')
101+
for th in headers:
102+
if th.text.strip() == 'Duration':
103+
th.string = 'Execution Time'
104+
#print("Renamed 'Duration' to 'Execution Time'")
105+
break
106+
else:
107+
print("'Duration' column not found in report.")
37108

38-
def pytest_html_results_table_row(report, cells):
39-
cells.insert(
40-
1, html.td(report.description if hasattr(report, "description") else "")
41-
)
109+
with open(report_path, 'w', encoding='utf-8') as f:
110+
f.write(str(soup))
42111

112+
# Register this function to run after everything is done
113+
atexit.register(rename_duration_column)
43114

44115
# Add logs and docstring to report
45116
@pytest.hookimpl(hookwrapper=True)
Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,42 @@
11
import logging
2+
import pytest
23
import time
3-
44
from pages.HomePage import HomePage
55

6-
import pytest
7-
8-
96
logger = logging.getLogger(__name__)
107

8+
# Define step-wise test actions for Golden Path
9+
golden_path_steps = [
10+
("01. Validate home page is loaded", lambda home: home.validate_home_page()),
11+
("02. Validate Upload of other than SQL files", lambda home: home.upload_unsupported_files()),
12+
("03. Validate Upload input files for SQL only", lambda home: home.upload_files()),
13+
("04. Validate translation process for uploaded files", lambda home: _timed_translation(home)),
14+
("05. Check batch history", lambda home: home.validate_batch_history()),
15+
("06. Download all files and return home", lambda home: home.validate_download_files()),
16+
]
1117

12-
@pytest.mark.testcase_id("TC001")
13-
def test_CodeGen_Golden_path_test(login_logout):
14-
"""Validate Golden path test case for Modernize your code Accelerator"""
15-
page = login_logout
16-
home_page = HomePage(page)
17-
logger.info("Step 1: Validate home page is loaded.")
18-
home_page.validate_home_page()
19-
logger.info("Step 2: Validate Upload of other than SQL files.")
20-
home_page.upload_unsupported_files()
21-
logger.info("Step 3: Validate Upload input files for SQL only.")
22-
home_page.upload_files()
23-
logger.info("Step 4: Validate translation process for uploaded files.")
18+
def _timed_translation(home):
2419
start = time.time()
25-
home_page.validate_translate()
20+
home.validate_translate()
2621
end = time.time()
27-
print(f"Translation process for uploaded files took {end - start:.2f} seconds")
28-
logger.info("Step 5: Check batch history.")
29-
home_page.validate_batch_history()
30-
logger.info("Step 6: Download all files and return home.")
31-
home_page.validate_download_files()
22+
logger.info(f"Translation process for uploaded files took {end - start:.2f} seconds")
23+
24+
@pytest.mark.parametrize("description, action", golden_path_steps, ids=[desc for desc, _ in golden_path_steps])
25+
def test_codegen_golden_path(login_logout, description, action, request):
26+
"""
27+
Executes golden path test steps for Modernize Your Code Accelerator with detailed logging.
28+
"""
29+
request.node._nodeid = description # To improve test output readability
30+
31+
page = login_logout
32+
home = HomePage(page)
33+
34+
logger.info(f"Running test step: {description}")
35+
try:
36+
action(home)
37+
except Exception:
38+
logger.error(f"Step failed: {description}", exc_info=True)
39+
raise
40+
41+
# Optional reporting hook
42+
request.node._report_sections.append(("call", "log", f"Step passed: {description}"))

0 commit comments

Comments
 (0)