"""
the testcase base class
"""
try:
import unittest2 as unittest
except ImportError:
import unittest
import imp
import inspect
import json
import os
from unittest import SkipTest
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.wait import WebDriverWait
from .config import BROWSER_MAPPING, Config, HolmiumConfig
from .env import ENV, LazyWebDriver, LazyWebDriverList
# pylint: disable=too-many-public-methods
[docs]class TestCase(unittest.TestCase):
"""
Base class for creating test classes for writing holmium driven
test cases. More details can be found at :ref:`testing-unittest`
"""
[docs] @classmethod
def setUpClass(cls):
"""
prepare the driver initialization based on the environment variables
that have been set. The driver is not actually initialized until the
test itself actually refers to it via `self.driver`.
"""
cls.driver = None
base_file = inspect.getfile(cls)
config_path = os.path.join(os.path.split(base_file)[0], "config")
browser = os.environ.get("HO_BROWSER", "firefox")
user_agent = os.environ.get("HO_USERAGENT", "")
remote = os.environ.get("HO_REMOTE", None)
environment = os.environ.get("HO_ENV", "development")
ignore_ssl = os.environ.get("HO_IGNORE_SSL_ERRORS", False)
fresh_instance = bool(int(os.environ.get("HO_BROWSER_PER_TEST", 0)))
cls.holmium_config = HolmiumConfig(
browser, remote, {}, user_agent, environment, ignore_ssl, fresh_instance
)
config = None
if os.path.isfile(config_path + ".json"):
config = json.loads(open(config_path + ".json").read())
elif os.path.isfile(config_path + ".py"):
config = imp.load_source("config", config_path + ".py").config
if config:
cls.config = Config(config, {"holmium": cls.holmium_config})
# pylint: disable=no-member
if remote:
driver_cls = BROWSER_MAPPING["remote"]
else:
if cls.holmium_config.browser not in BROWSER_MAPPING:
raise SkipTest(
"Unknown browser (%s) specified in HO_BROWSER"
% (cls.holmium_config.browser)
)
driver_cls = BROWSER_MAPPING[cls.holmium_config.browser]
cls.driver = ENV.setdefault(
"driver", LazyWebDriver(driver_cls, cls.holmium_config)
)
cls.drivers = ENV.setdefault("drivers", LazyWebDriverList())
if hasattr(super(), "setUpClass"):
super().setUpClass()
[docs] @classmethod
def tearDownClass(cls):
"""
quit the driver after the test run (or after all the test methods
in the class have finished if ``HO_BROWSER_PER_TEST`` is set).
"""
# pylint:disable=no-member
if ENV.get("driver", None) and cls.holmium_config.fresh_instance:
for driver in ENV["drivers"]:
driver.safe_quit()
if hasattr(super(), "tearDownClass"):
super().tearDownClass()
[docs] def tearDown(self):
"""
clear the cookies on the driver after each test
"""
if ENV.get("driver", None):
for driver in ENV["drivers"]:
driver.safe_clear()
super().tearDown()
# helper assertions
# pylint: disable=invalid-name
[docs] def assertElementTextEqual(self, element, text, msg=None):
"""
Fail if the text attribute of the element does not match
"""
self.assertEqual(element.text, text, msg)
[docs] def assertElementAttributeEqual(self, element, key, value, msg=None):
"""
Fail if the element does not have the specified attribute value
"""
self.assertEqual(element.get_attribute(key), value, msg)
[docs] def assertElementDisplayed(self, element, msg=None):
"""
Fail if the element is not visible
"""
self.assertTrue(element.is_displayed(), msg)
[docs] def assertElementsDisplayed(self, elements, msg=None):
"""
Fail if any of the elements in the element collection are not
visible
"""
_ = elements.values() if isinstance(elements, dict) else elements
self.assertTrue(all(el.is_displayed() for el in _), msg)
[docs] def assertElementCSS(self, element, css_property, value, msg=None):
# noqa: E501
"""
Fail if the element does not exhibit the correct css property value.
The value of the elements css property is the one returned by
:meth:`selenium.webdriver.remote.webelement.WebElement.value_of_css_property`
"""
self.assertEqual(element.value_of_css_property(css_property), value, msg)
[docs] def assertElementSize(self, element, width, height, msg=None):
"""Fail if the element size does not match the provided values"""
_expected = {"height": height, "width": width}
self.assertEqual(_expected, element.size, msg)
[docs] def assertConditionWithWait(
self, driver, condition, timeout=0, msg=None, ignored_exceptions=None
):
"""Fail if the condition specified does not hold for the element
within the specified timeout
:param driver: the selenium driver
:param condition: an instance of
:mod:`selenium.webdriver.support.expected_conditions`
:param msg: the failure message when timeout, could be a string or a
callable without arguments that returns a string
:param timeout: to be passed to
`selenium.webdriver.support.wait.WebDriverWait`
:param ignored_exceptions: to be passed to
`selenium.webdriver.support.wait.WebDriverWait`
"""
try:
wait = WebDriverWait(driver, timeout, ignored_exceptions=ignored_exceptions)
wait.until(condition)
except TimeoutException:
_msg = self._formatMessage(
msg() if callable(msg) else msg,
"Timeout waiting on condition %s" % condition,
)
raise self.failureException(_msg)