-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconftest.py
More file actions
156 lines (130 loc) · 5.42 KB
/
conftest.py
File metadata and controls
156 lines (130 loc) · 5.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
"""
Pytest Configuration and Fixtures
Professional setup with screenshot capture, Allure integration, and optimized performance
Incorporates enterprise-level best practices
"""
import pytest
import logging
import allure
from pathlib import Path
from datetime import datetime
from utils.browser_factory import BrowserFactory
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def pytest_addoption(parser):
"""Add custom command line options"""
parser.addoption(
"--browser",
action="store",
default="chrome",
help="Browser to run tests on: chrome, firefox, or edge"
)
parser.addoption(
"--headless",
action="store_true",
default=False,
help="Run tests in headless mode"
)
@pytest.fixture(scope='class')
def driver(request):
"""
WebDriver fixture with class scope for optimal performance.
Creates one driver instance per test class.
Includes automatic screenshot capture on test failure.
This fixture also assigns the driver to the test class for
Page Object Model pattern (accessible via self.driver).
Args:
request: Pytest request object
Yields:
WebDriver: Configured browser driver instance
"""
browser_name = request.config.getoption("--browser")
factory = BrowserFactory()
driver = factory.create_driver(browser_name)
# Get context name safely (handles both class and function scoped tests)
test_context = request.cls.__name__ if request.cls else "function_tests"
logger.info(f"Driver created for {test_context}")
# Assign driver to test class for POM pattern (e.g., self.driver)
if request.cls:
request.cls.driver = driver
yield driver
# Teardown: quit driver after all tests in class
logger.info(f"Closing driver for {test_context}")
driver.quit()
@pytest.hookimpl(tryfirst=True, hookwrapper=True)
def pytest_runtest_makereport(item, call):
"""
Pytest hook to capture screenshots on test failure.
Attaches screenshot and page source to Allure report automatically.
Works with any WebDriver fixture name by detecting screenshot capability.
"""
outcome = yield
report = outcome.get_result()
# Only capture screenshot on test failure during test execution
if report.when == 'call' and report.failed:
# Find driver in test arguments (supports any fixture name with screenshot capability)
driver = None
for fixture_value in item.funcargs.values():
if hasattr(fixture_value, 'save_screenshot'):
driver = fixture_value
break
if driver:
# Create screenshots directory if not exists
screenshot_dir = Path("reports/screenshots")
screenshot_dir.mkdir(parents=True, exist_ok=True)
# Generate unique filename
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
test_name = item.name
screenshot_path = screenshot_dir / f"{test_name}_{timestamp}.png"
try:
# Capture and save screenshot to file (for local debugging)
driver.save_screenshot(str(screenshot_path))
logger.info(f"Screenshot saved: {screenshot_path}")
# Attach screenshot to Allure report (for CI/CD)
allure.attach(
driver.get_screenshot_as_png(),
name=f"Failure_{test_name}",
attachment_type=allure.attachment_type.PNG
)
# Attach page source for debugging
allure.attach(
driver.page_source,
name=f"Page_Source_{test_name}",
attachment_type=allure.attachment_type.HTML
)
# Attach browser console logs if available (Chrome only)
try:
if driver.capabilities.get('browserName') == 'chrome':
console_logs = driver.get_log('browser')
if console_logs:
log_text = "\n".join([f"{log['level']}: {log['message']}" for log in console_logs])
allure.attach(
log_text,
name=f"Console_Logs_{test_name}",
attachment_type=allure.attachment_type.TEXT
)
except Exception:
pass # Browser logs not critical
except Exception as e:
logger.error(f"Failed to capture screenshot: {e}")
def pytest_configure(config):
"""Configure pytest with custom markers"""
config.addinivalue_line(
"markers", "smoke: mark test as smoke test (quick validation)"
)
config.addinivalue_line(
"markers", "regression: mark test as regression test (full suite)"
)
config.addinivalue_line(
"markers", "user_flows: mark test as user flow test (end-to-end scenarios)"
)
config.addinivalue_line(
"markers", "product: mark test as product test (product-related features)"
)
config.addinivalue_line(
"markers", "ui: mark test as UI test (for conditional screenshot capture)"
)