Repository URL to install this package:
|
Version:
2.4.3 ▾
|
#-----------------------------------------------------------------------------
# Copyright (c) 2012 - 2022, Anaconda, Inc., and Bokeh Contributors.
# All rights reserved.
#
# The full license is in the file LICENSE.txt, distributed with this software.
#-----------------------------------------------------------------------------
''' Define a Pytest plugin for a log file fixture
'''
#-----------------------------------------------------------------------------
# Boilerplate
#-----------------------------------------------------------------------------
from __future__ import annotations
import logging # isort:skip
log = logging.getLogger(__name__)
#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------
# Standard library imports
from typing import (
TYPE_CHECKING,
Callable,
Iterator,
List,
NoReturn,
Sequence,
)
from warnings import warn
# External imports
import pytest
if TYPE_CHECKING:
import py
from _pytest import config, nodes
from selenium.webdriver.remote.webdriver import WebDriver
#-----------------------------------------------------------------------------
# Globals and constants
#-----------------------------------------------------------------------------
__all__ = (
'driver',
'has_no_console_errors',
'pytest_report_collectionfinish',
)
#-----------------------------------------------------------------------------
# General API
#-----------------------------------------------------------------------------
def pytest_report_collectionfinish(config: config.Config, startdir: py.path.local, items: Sequence[nodes.Item]) -> List[str]:
'''
'''
driver_name: str = config.getoption('driver', 'chrome').lower()
asserts = "ON" if driver_name == "chrome" else "OFF"
return ["", f"Bokeh selenium tests using {driver_name!r} driver (no-console-error assertions: {asserts})"]
@pytest.fixture(scope="session")
def driver(pytestconfig: config.Config) -> Iterator[WebDriver]:
''' Select and configure a Selenium webdriver for integration tests.
'''
driver_name: str = pytestconfig.getoption('driver', 'chrome').lower()
def chrome() -> WebDriver:
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.webdriver import WebDriver as Chrome
options = Options()
options.add_argument("--headless")
options.add_argument("--no-sandbox")
options.add_argument("--window-size=1920x1080")
return Chrome(options=options)
def firefox() -> WebDriver:
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.firefox.webdriver import WebDriver as Firefox
options = Options()
options.add_argument("--headless")
options.add_argument("--window-size=1920x1080")
return Firefox(options=options)
def safari() -> WebDriver:
from selenium.webdriver.safari.webdriver import WebDriver as Safari
return Safari()
driver: WebDriver
if driver_name == "chrome":
driver = chrome()
elif driver_name == "firefox":
driver = firefox()
elif driver_name == "safari":
driver = safari()
else:
raise ValueError("expected 'chrome', 'firefox' or 'safari'")
driver.implicitly_wait(10)
yield driver
driver.quit()
@pytest.fixture(scope="session")
def has_no_console_errors(pytestconfig: config.Config) -> Callable[[WebDriver], bool | NoReturn]:
''' Provide a function to assert no browser console errors are present.
Unfortunately logs are only accessibly with Chrome web driver, see e.g.
https://github.com/mozilla/geckodriver/issues/284
For non-Chrome webdrivers this check always returns True.
'''
driver_name: str = pytestconfig.getoption('driver').lower()
if driver_name == "chrome":
def func(driver: WebDriver) -> bool | NoReturn:
logs = driver.get_log('browser')
severe_errors = [x for x in logs if x.get('level') == 'SEVERE']
non_network_errors = [l for l in severe_errors if l.get('type') != 'network']
if len(non_network_errors) == 0:
if len(severe_errors) != 0:
warn(f"There were severe network errors (this may or may not have affected your test): {severe_errors}")
return True
# XXX: no return should be needed with NoReturn type (type-checker bug?)
return pytest.fail(f"Console errors: {non_network_errors}")
else:
def func(driver: WebDriver) -> bool | NoReturn:
return True
return func
#-----------------------------------------------------------------------------
# Dev API
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Private API
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------