repos
/ timestrap-django master

timestrap-django

mirror archived upstream

Time tracking you can host anywhere, built on Django. Full export support in multiple formats and easily extensible.

djangodockerhandcodedpythonself-hostedtime-trackingtimetracker

3.6 KB · 110 lines · Python Raw History
  1from os import environ
  2from time import sleep
  3
  4from django.contrib.staticfiles.testing import StaticLiveServerTestCase
  5from django.test import override_settings
  6from django.core.management import call_command
  7
  8from selenium.webdriver import Firefox as FirefoxDriver
  9from selenium.webdriver.firefox.options import Options as FirefoxOptions
 10from selenium.webdriver.common.keys import Keys
 11
 12
 13@override_settings(
 14    STATICFILES_STORAGE="django.contrib.staticfiles.storage.StaticFilesStorage"
 15)
 16class SeleniumTestCase(StaticLiveServerTestCase):
 17    def _flakyTestWrapper(self):
 18        testMethod = getattr(self, self.flakyTestMethodName)
 19        retries = 0
 20        while retries < 3:
 21            try:
 22                return testMethod()
 23            except Exception as e:
 24                print("\nRetrying flaky test %s" % self.flakyTestMethodName)
 25                retries += 1
 26                lastException = e
 27                sleep(1)
 28        raise lastException
 29
 30    def run(self, result=None):
 31        self.flakyTestMethodName = self._testMethodName
 32        self._testMethodName = "_flakyTestWrapper"
 33        super().run(result)
 34        self._testMethodName = self.flakyTestMethodName
 35
 36    @classmethod
 37    def setUpClass(cls):
 38        options = FirefoxOptions()
 39        if environ.get("MOZ_HEADLESS") != "0":
 40            # Setting environ var might seem redundant but some versions of firefox
 41            # and geckodriver fail to obey -headless properly
 42            environ["MOZ_HEADLESS"] = "1"
 43            options.add_argument("-headless")
 44        cls.driver = FirefoxDriver(firefox_options=options)
 45        cls.driver.maximize_window()
 46        cls.driver.implicitly_wait(2)
 47        cls.driver.set_page_load_timeout(30)
 48
 49        super().setUpClass()
 50
 51    @classmethod
 52    def tearDownClass(cls):
 53        cls.driver.quit()
 54        super().tearDownClass()
 55
 56    def setUp(self):
 57        call_command("migrate", verbosity=0)
 58        call_command("fake", verbosity=0, iterations=1)
 59
 60        self.logIn()
 61
 62        super().setUp()
 63
 64    def logIn(self):
 65        self.driver.get("%s%s" % (self.live_server_url, "/login/"))
 66
 67        input_username = self.find("input-username")
 68        input_password = self.find("input-password")
 69        button_submit = self.find("button-submit")
 70
 71        input_username.send_keys("admin")
 72        input_password.send_keys("admin")
 73        button_submit.click()
 74
 75        self.find("app")
 76
 77    def clear(self, element):
 78        # Selenium's clear command doesn't work
 79        value = element.get_attribute("value")
 80        for character in value:
 81            element.send_keys(Keys.BACK_SPACE)
 82
 83    def find(self, id, element=None):
 84        # Our primary way of finding things
 85        if element:
 86            return element.find_element_by_id(id)
 87        else:
 88            return self.driver.find_element_by_id(id)
 89
 90    def contains(self, string, element=None):
 91        # Finding things by a text string
 92        xpath = "//*[contains(text(), '%s')]" % (string,)
 93        if element:
 94            return element.find_element_by_xpath(xpath)
 95        else:
 96            return self.driver.find_element_by_xpath(xpath)
 97
 98    def select(self, value, element):
 99        # Our select field uses the select2 jQuery plugin
100        element = element.find_element_by_xpath("..")
101        element_arrow = element.find_element_by_class_name(
102            "select2-selection__arrow"
103        )  # noqa: E501
104        element_arrow.click()
105        element_search = self.driver.find_element_by_class_name(
106            "select2-search__field"
107        )  # noqa: E501
108        element_search.send_keys(value)
109        element_search.send_keys(Keys.RETURN)