# noinspection PyPackageRequirements
import pytest
import _pytest
# noinspection PyPackageRequirements
from selenium import webdriver
# noinspection PyPackageRequirements
import time
from WebDriverTester import WebDriverTester
from TestHelper import Singleton
from tlib.base import TLibHelper
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait


# noinspection PyMethodParameters
class SeleniumTester(WebDriverTester):
    __metaclass__ = Singleton
    _homepage = None

    def _get_browser(self):
        """
        Returns Instance of the WebDriver browser
        @rtype: webdriver.Remote
        """
        return self._driver

    def _set_browser(self, browser):
        """
        Instance of the WebDriver browser
        @type browser: webdriver.Remote
        """
        self._driver = browser

    browser = property(_get_browser, _set_browser)

    def _get_homepage(self):
        """
        Instance of the WebDriver homepage
        """
        return self._homepage

    def _set_homepage(self, homepage):
        """
        Instance of the WebDriver homepage
        @type homepage: webdriver.Remote
        """
        self._homepage = homepage

    homepage = property(_get_homepage, _set_homepage)

    @pytest.fixture(scope='class', autouse=True)
    def initialize_selenium_class(self, browser, request, tlib_logger, initialize_webdriver_class):
        """
        @type browser: webdriver.Remote
        @type browser: webdriver.Remote
        @type request: FixtureRequest
        @type tlib_logger: logging
        """
        self.browser = browser

        # Only initialize homepage if it wasn't already initialized
        if self.homepage is None:
            # noinspection PyUnresolvedReferences
            try:
                self.homepage = TLibHelper.get_base_url(request, tlib_logger)
            except _pytest.runner.Failed:
                #If this exception is triggered, command line option --base_url was not specified
                self.homepage = ''

    @pytest.fixture(scope='function', autouse=True)
    def setup_selenium_test(self, request, browser, test_logger, setup_webdriver_test):
        """
        Goes to homepage before each test, unless marker skipsetup is given

        @type request: FixtureRequest
        @type test_logger: logging
        @type browser: webdriver.Remote
        """

        #Skip going to homepage if marker skipsetup is specified
        if "skipsetup" not in request.node.function.__dict__:
            #Before clearing cookies, need to go to home screen, to ensure it's the current domain
            self.go_home(save_screenshot=False)
            browser.delete_all_cookies()
            self.go_home()
        else:
            test_logger.info("Skipping setup")

    def navigate(self, page, save_screenshot=True):
        """
        Navigate to "page"
        """
        self.test_logger.info(u"Navigating to %s" % page)
        self.browser.get(page)
        if save_screenshot:
            self.save_screenshot(u"Navigate to %s" % page)

    def go_home(self, save_screenshot=True):
        """
        Navigate to home page
        """
        if self.homepage:
            self.navigate(self.homepage, save_screenshot=False)
            if save_screenshot:
                self.save_screenshot("Homepage")

    def wait_for_page_loaded(self, timeout=10):
        """
        Waist until document.readyState is equal to complete
        @type timeout: Integer
        @param timeout: Number of seconds before timing out
        """
        if self._request.config.getoption('browser') != 'firefox_no_js':
            condition = lambda *args: self._driver.execute_script("return document.readyState") == "complete"
            try:
                WebDriverWait(self.browser, timeout).until(condition)
            except TimeoutException:
                self.test_logger.error('Timeout while waiting for page to load')
                # noinspection PyUnresolvedReferences
                pytest.fail('Timeout while waiting for page to load')
        else:
            time.sleep(2.0)
        self.tlib_logger.debug("Page '%s' finished loading" % self._driver.current_url)
