Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

selenium.py 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import sys
  2. import unittest
  3. from contextlib import contextmanager
  4. from django.test import LiveServerTestCase, tag
  5. from django.utils.module_loading import import_string
  6. from django.utils.text import capfirst
  7. class SeleniumTestCaseBase(type(LiveServerTestCase)):
  8. # List of browsers to dynamically create test classes for.
  9. browsers = []
  10. # Sentinel value to differentiate browser-specific instances.
  11. browser = None
  12. def __new__(cls, name, bases, attrs):
  13. """
  14. Dynamically create new classes and add them to the test module when
  15. multiple browsers specs are provided (e.g. --selenium=firefox,chrome).
  16. """
  17. test_class = super().__new__(cls, name, bases, attrs)
  18. # If the test class is either browser-specific or a test base, return it.
  19. if test_class.browser or not any(name.startswith('test') and callable(value) for name, value in attrs.items()):
  20. return test_class
  21. elif test_class.browsers:
  22. # Reuse the created test class to make it browser-specific.
  23. # We can't rename it to include the browser name or create a
  24. # subclass like we do with the remaining browsers as it would
  25. # either duplicate tests or prevent pickling of its instances.
  26. first_browser = test_class.browsers[0]
  27. test_class.browser = first_browser
  28. # Create subclasses for each of the remaining browsers and expose
  29. # them through the test's module namespace.
  30. module = sys.modules[test_class.__module__]
  31. for browser in test_class.browsers[1:]:
  32. browser_test_class = cls.__new__(
  33. cls,
  34. "%s%s" % (capfirst(browser), name),
  35. (test_class,),
  36. {'browser': browser, '__module__': test_class.__module__}
  37. )
  38. setattr(module, browser_test_class.__name__, browser_test_class)
  39. return test_class
  40. # If no browsers were specified, skip this class (it'll still be discovered).
  41. return unittest.skip('No browsers specified.')(test_class)
  42. @classmethod
  43. def import_webdriver(cls, browser):
  44. return import_string("selenium.webdriver.%s.webdriver.WebDriver" % browser)
  45. def create_webdriver(self):
  46. return self.import_webdriver(self.browser)()
  47. @tag('selenium')
  48. class SeleniumTestCase(LiveServerTestCase, metaclass=SeleniumTestCaseBase):
  49. implicit_wait = 10
  50. @classmethod
  51. def setUpClass(cls):
  52. cls.selenium = cls.create_webdriver()
  53. cls.selenium.implicitly_wait(cls.implicit_wait)
  54. super().setUpClass()
  55. @classmethod
  56. def _tearDownClassInternal(cls):
  57. # quit() the WebDriver before attempting to terminate and join the
  58. # single-threaded LiveServerThread to avoid a dead lock if the browser
  59. # kept a connection alive.
  60. if hasattr(cls, 'selenium'):
  61. cls.selenium.quit()
  62. super()._tearDownClassInternal()
  63. @contextmanager
  64. def disable_implicit_wait(self):
  65. """Disable the default implicit wait."""
  66. self.selenium.implicitly_wait(0)
  67. try:
  68. yield
  69. finally:
  70. self.selenium.implicitly_wait(self.implicit_wait)