|
| 1 | +import datetime |
1 | 2 | import logging
|
2 | 3 | import os
|
3 | 4 | import platform
|
| 5 | +import re |
4 | 6 | from typing import Callable, List, Tuple
|
5 | 7 |
|
6 | 8 | import pytest
|
7 | 9 | from selenium import webdriver
|
8 | 10 | from selenium.common.exceptions import WebDriverException
|
| 11 | +from selenium.webdriver import Firefox |
9 | 12 | from selenium.webdriver.firefox.options import Options
|
10 | 13 |
|
11 | 14 |
|
| 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 | + |
12 | 73 | def pytest_addoption(parser):
|
13 | 74 | """Set custom command-line options"""
|
14 | 75 | parser.addoption(
|
@@ -54,6 +115,17 @@ def pytest_addoption(parser):
|
54 | 115 | )
|
55 | 116 |
|
56 | 117 |
|
| 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 | + |
57 | 129 | @pytest.fixture()
|
58 | 130 | def opt_headless(request):
|
59 | 131 | return request.config.getoption("--run-headless")
|
@@ -194,20 +266,10 @@ def screenshot(driver: webdriver.Firefox, opt_ci: bool) -> Callable:
|
194 | 266 | Factory fixture that returns a screenshot function.
|
195 | 267 | """
|
196 | 268 |
|
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 |
211 | 273 |
|
212 | 274 |
|
213 | 275 | @pytest.fixture()
|
|
0 commit comments