#-----------------------------------------------------------------------------
# Copyright (c) 2012 - 2021, 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
#-----------------------------------------------------------------------------
import logging # isort:skip
log = logging.getLogger(__name__)

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

# Standard library imports
from warnings import warn

# External imports
import pytest
from selenium import webdriver

#-----------------------------------------------------------------------------
# Globals and constants
#-----------------------------------------------------------------------------

__all__ = (
    'driver',
    'has_no_console_errors',
    'pytest_report_collectionfinish',
)

#-----------------------------------------------------------------------------
# General API
#-----------------------------------------------------------------------------

def pytest_report_collectionfinish(config, startdir, items):
    '''

    '''
    driver  = config.getoption('driver', 'chrome').lower()
    asserts = "ON" if driver == "chrome" else "OFF"
    return ["", "Bokeh selenium tests using %r driver (no-console-error assertions: %s)" % (driver, asserts)]

@pytest.yield_fixture(scope="session")
def driver(pytestconfig):
    ''' Select and configure a Selenium webdriver for integration tests.

    '''
    driver_name  = pytestconfig.getoption('driver', 'chrome').lower()

    if driver_name == "chrome":
        from selenium.webdriver.chrome.options import Options
        options = Options()
        options.add_argument("--headless")
        options.add_argument("--no-sandbox")
        options.add_argument("--window-size=1920x1080")
        driver = webdriver.Chrome(options=options)

    elif driver_name == "firefox":
        from selenium.webdriver.firefox.options import Options
        options = Options()
        options.add_argument("--headless")
        options.add_argument("--window-size=1920x1080")
        driver = webdriver.Firefox(options=options)

    elif driver_name == "safari":
        driver = webdriver.Safari()

    driver.implicitly_wait(10)

    yield driver

    driver.quit()

@pytest.fixture(scope="session")
def has_no_console_errors(pytestconfig):
    ''' 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  = pytestconfig.getoption('driver').lower()

    if driver_name == "chrome":

        def func(driver):
            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("There were severe network errors (this may or may not have affected your test): %s" % severe_errors)
                return True

            pytest.fail('Console errors: %s' % non_network_errors)


    else:
        def func(driver):
            return True

    return func

#-----------------------------------------------------------------------------
# Dev API
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Private API
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Code
#-----------------------------------------------------------------------------
