Skip to content

Commit b05e9e4

Browse files
authored
Merge pull request #143 from mozilla/sl/exception-wrapper
Exception Wrapper
2 parents 3d8545a + 8922fbb commit b05e9e4

File tree

2 files changed

+84
-17
lines changed

2 files changed

+84
-17
lines changed

.github/workflows/smoke.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,11 @@ jobs:
2828
- name: Run Smoke Tests in Win
2929
run: |
3030
pipenv run pytest --fx-executable ./firefox/firefox -n 4 .
31-
mv artifacts artifacts-win
31+
$env:TEST_EXIT_CODE = $LASTEXITCODE
32+
mv artifacts artifacts-win || true
33+
exit $env:TEST_EXIT_CODE
3234
- name: Upload artifacts
35+
if: always()
3336
uses: actions/upload-artifact@v4
3437
with:
3538
name: artifacts-win
@@ -55,9 +58,11 @@ jobs:
5558
pipenv install;
5659
- name: Run Smoke Tests in MacOS
5760
run: |
58-
pipenv run pytest --fx-executable ./firefox/firefox -n 4 tests
59-
mv artifacts artifacts-mac
61+
pipenv run pytest --fx-executable ./firefox/firefox -s -n 4 . || TEST_EXIT_CODE=$?
62+
mv artifacts artifacts-mac || true
63+
exit $TEST_EXIT_CODE
6064
- name: Upload artifacts
65+
if: always()
6166
uses: actions/upload-artifact@v4
6267
with:
6368
name: artifacts-mac

conftest.py

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,75 @@
1+
import datetime
12
import logging
23
import os
34
import platform
5+
import re
46
from typing import Callable, List, Tuple
57

68
import pytest
79
from selenium import webdriver
810
from selenium.common.exceptions import WebDriverException
11+
from selenium.webdriver import Firefox
912
from selenium.webdriver.firefox.options import Options
1013

1114

15+
def screenshot_content(driver: Firefox, opt_ci: bool, test_name: str) -> None:
16+
"""
17+
Screenshots the current browser, saves with appropriate test name and date for reference
18+
"""
19+
current_time = str(datetime.datetime.now())
20+
current_time = re.sub(r"[^\w_. -]", "_", current_time)
21+
filename = f"{test_name}_{current_time}_image"
22+
_screenshot(filename, driver, opt_ci)
23+
24+
25+
def log_content(opt_ci: bool, driver: Firefox, test_name: str) -> None:
26+
"""
27+
Logs the current browser content, with the appropriate test name and date for reference.
28+
"""
29+
artifacts_loc = "artifacts" if opt_ci else ""
30+
current_time = str(datetime.datetime.now())
31+
current_time = re.sub(r"[^\w_. -]", "_", current_time)
32+
fullpath_chrome = os.path.join(
33+
artifacts_loc, f"{test_name}_{current_time}_content.txt"
34+
)
35+
fullpath_content = os.path.join(
36+
artifacts_loc, f"{test_name}_{current_time}_chrome.txt"
37+
)
38+
39+
# Save Chrome context page source
40+
with open(fullpath_chrome, "w", encoding="utf-8") as fh:
41+
with driver.context(driver.CONTEXT_CHROME):
42+
output_contents = driver.page_source
43+
fh.write(output_contents)
44+
45+
# Save Content context page source
46+
with open(fullpath_content, "w", encoding="utf-8") as fh:
47+
output_contents = driver.page_source
48+
fh.write(output_contents)
49+
return
50+
51+
52+
def pytest_exception_interact(node, call, report):
53+
"""
54+
Method that wraps all test execution, on any exception/failure an artifact with the information about the failure is kept.
55+
"""
56+
if report.failed:
57+
try:
58+
test_name = node.name
59+
logging.error(f"Handling exception for test: {test_name}")
60+
logging.error(
61+
f"NODE LOGS HERE {node.funcargs}\n THE FAILED TEST: {test_name}"
62+
)
63+
driver = node.funcargs.get("driver")
64+
opt_ci = node.funcargs.get("opt_ci")
65+
if driver:
66+
log_content(opt_ci, driver, test_name)
67+
screenshot_content(driver, opt_ci, test_name)
68+
except Exception as e:
69+
logging.warning("Something went wrong with the exception catching.")
70+
raise e
71+
72+
1273
def pytest_addoption(parser):
1374
"""Set custom command-line options"""
1475
parser.addoption(
@@ -54,6 +115,17 @@ def pytest_addoption(parser):
54115
)
55116

56117

118+
def _screenshot(filename: str, driver: Firefox, opt_ci: bool):
119+
if not filename.endswith(".png"):
120+
filename = filename + ".png"
121+
artifacts_loc = ""
122+
if opt_ci:
123+
artifacts_loc = "artifacts"
124+
fullpath = os.path.join(artifacts_loc, filename)
125+
driver.save_screenshot(fullpath)
126+
return fullpath
127+
128+
57129
@pytest.fixture()
58130
def opt_headless(request):
59131
return request.config.getoption("--run-headless")
@@ -194,20 +266,10 @@ def screenshot(driver: webdriver.Firefox, opt_ci: bool) -> Callable:
194266
Factory fixture that returns a screenshot function.
195267
"""
196268

197-
def _screenshot(filename: str) -> str:
198-
"""
199-
Given a short filename, save a screenshot and return the image's full path.
200-
"""
201-
if not filename.endswith(".png"):
202-
filename = filename + ".png"
203-
artifacts_loc = ""
204-
if opt_ci:
205-
artifacts_loc = "artifacts"
206-
fullpath = os.path.join(artifacts_loc, filename)
207-
driver.save_screenshot(fullpath)
208-
return fullpath
209-
210-
return _screenshot
269+
def screenshot_wrapper(filename: str) -> str:
270+
return _screenshot(filename, driver, opt_ci)
271+
272+
return screenshot_wrapper
211273

212274

213275
@pytest.fixture()

0 commit comments

Comments
 (0)