Loading AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ answer newbie questions, and generally made Django that much better: ajs <adi@sieker.info> Akis Kesoglou <akiskesoglou@gmail.com> Aksel Ethem <aksel.ethem@gmail.com> Akshesh Doshi <aksheshdoshi+django@gmail.com> alang@bright-green.com Alasdair Nicol <http://al.sdair.co.uk/> Albert Wang <aywang31@gmail.com> Loading django/contrib/admin/tests.py +3 −27 Original line number Diff line number Diff line import os from unittest import SkipTest from django.contrib.staticfiles.testing import StaticLiveServerTestCase from django.test import modify_settings, tag from django.utils.module_loading import import_string from django.test import modify_settings from django.test.selenium import SeleniumTestCase from django.utils.translation import ugettext as _ Loading @@ -14,11 +11,10 @@ class CSPMiddleware(object): return response @tag('selenium') @modify_settings( MIDDLEWARE_CLASSES={'append': 'django.contrib.admin.tests.CSPMiddleware'}, ) class AdminSeleniumWebDriverTestCase(StaticLiveServerTestCase): class AdminSeleniumTestCase(SeleniumTestCase, StaticLiveServerTestCase): available_apps = [ 'django.contrib.admin', Loading @@ -27,26 +23,6 @@ class AdminSeleniumWebDriverTestCase(StaticLiveServerTestCase): 'django.contrib.sessions', 'django.contrib.sites', ] webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver' @classmethod def setUpClass(cls): if not os.environ.get('DJANGO_SELENIUM_TESTS', False): raise SkipTest('Selenium tests not requested') try: cls.selenium = import_string(cls.webdriver_class)() except Exception as e: raise SkipTest('Selenium webdriver "%s" not installed or not ' 'operational: %s' % (cls.webdriver_class, str(e))) cls.selenium.implicitly_wait(10) # This has to be last to ensure that resources are cleaned up properly! super(AdminSeleniumWebDriverTestCase, cls).setUpClass() @classmethod def _tearDownClassInternal(cls): if hasattr(cls, 'selenium'): cls.selenium.quit() super(AdminSeleniumWebDriverTestCase, cls)._tearDownClassInternal() def wait_until(self, callback, timeout=10): """ Loading django/test/selenium.py 0 → 100644 +73 −0 Original line number Diff line number Diff line from __future__ import unicode_literals import sys import unittest from django.test import LiveServerTestCase, tag from django.utils.module_loading import import_string from django.utils.six import with_metaclass from django.utils.text import capfirst class SeleniumTestCaseBase(type(LiveServerTestCase)): # List of browsers to dynamically create test classes for. browsers = [] # Sentinel value to differentiate browser-specific instances. browser = None def __new__(cls, name, bases, attrs): """ Dynamically create new classes and add them to the test module when multiple browsers specs are provided (e.g. --selenium=firefox,chrome). """ test_class = super(SeleniumTestCaseBase, cls).__new__(cls, name, bases, attrs) # If the test class is either browser-specific or a test base, return it. if test_class.browser or not any(name.startswith('test') and callable(value) for name, value in attrs.items()): return test_class elif test_class.browsers: # Reuse the created test class to make it browser-specific. # We can't rename it to include the browser name or create a # subclass like we do with the remaining browsers as it would # either duplicate tests or prevent pickling of its instances. first_browser = test_class.browsers[0] test_class.browser = first_browser # Create subclasses for each of the remaining browsers and expose # them through the test's module namespace. module = sys.modules[test_class.__module__] for browser in test_class.browsers[1:]: browser_test_class = cls.__new__( cls, str("%s%s" % (capfirst(browser), name)), (test_class,), {'browser': browser, '__module__': test_class.__module__} ) setattr(module, browser_test_class.__name__, browser_test_class) return test_class # If no browsers were specified, skip this class (it'll still be discovered). return unittest.skip('No browsers specified.')(test_class) @classmethod def import_webdriver(cls, browser): return import_string("selenium.webdriver.%s.webdriver.WebDriver" % browser) def create_webdriver(self): return self.import_webdriver(self.browser)() @tag('selenium') class SeleniumTestCase(with_metaclass(SeleniumTestCaseBase, LiveServerTestCase)): @classmethod def setUpClass(cls): cls.selenium = cls.create_webdriver() cls.selenium.implicitly_wait(10) super(SeleniumTestCase, cls).setUpClass() @classmethod def _tearDownClassInternal(cls): # quit() the WebDriver before attempting to terminate and join the # single-threaded LiveServerThread to avoid a dead lock if the browser # kept a connection alive. if hasattr(cls, 'selenium'): cls.selenium.quit() super(SeleniumTestCase, cls)._tearDownClassInternal() docs/internals/contributing/writing-code/unit-tests.txt +9 −5 Original line number Diff line number Diff line Loading @@ -119,16 +119,20 @@ Going beyond that, you can specify an individual test method like this:: Running the Selenium tests -------------------------- Some tests require Selenium and a Web browser (Firefox, Google Chrome, or Internet Explorer). To allow those tests to be run rather than skipped, you must install the selenium_ package into your Python path and run the tests with the ``--selenium`` option:: Some tests require Selenium and a Web browser. To run these tests, you must install the selenium_ package and run the tests with the ``--selenium=<BROWSERS>`` option. For example, if you have Firefox and Google Chrome installed:: $ ./runtests.py --settings=test_sqlite --selenium admin_inlines $ ./runtests.py --selenium=firefox,chrome See the `selenium.webdriver`_ package for the list of available browsers. Specifying ``--selenium`` automatically sets ``--tags=selenium`` to run only the tests that require selenium. .. _selenium.webdriver: https://github.com/SeleniumHQ/selenium/tree/master/py/selenium/webdriver .. _running-unit-tests-dependencies: Running all the tests Loading tests/admin_changelist/tests.py +3 −12 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ from django.contrib import admin from django.contrib.admin.models import LogEntry from django.contrib.admin.options import IncorrectLookupParameters from django.contrib.admin.templatetags.admin_list import pagination from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase from django.contrib.admin.tests import AdminSeleniumTestCase from django.contrib.admin.views.main import ALL_VAR, SEARCH_VAR, ChangeList from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType Loading Loading @@ -882,10 +882,9 @@ class AdminLogNodeTestCase(TestCase): @override_settings(ROOT_URLCONF='admin_changelist.urls') class SeleniumFirefoxTests(AdminSeleniumWebDriverTestCase): class SeleniumTests(AdminSeleniumTestCase): available_apps = ['admin_changelist'] + AdminSeleniumWebDriverTestCase.available_apps webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver' available_apps = ['admin_changelist'] + AdminSeleniumTestCase.available_apps def setUp(self): User.objects.create_superuser(username='super', password='secret', email=None) Loading Loading @@ -915,11 +914,3 @@ class SeleniumFirefoxTests(AdminSeleniumWebDriverTestCase): '%s #result_list tbody tr:first-child .action-select' % form_id) row_selector.click() self.assertEqual(selection_indicator.text, "1 of 1 selected") class SeleniumChromeTests(SeleniumFirefoxTests): webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver' class SeleniumIETests(SeleniumFirefoxTests): webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver' Loading
AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ answer newbie questions, and generally made Django that much better: ajs <adi@sieker.info> Akis Kesoglou <akiskesoglou@gmail.com> Aksel Ethem <aksel.ethem@gmail.com> Akshesh Doshi <aksheshdoshi+django@gmail.com> alang@bright-green.com Alasdair Nicol <http://al.sdair.co.uk/> Albert Wang <aywang31@gmail.com> Loading
django/contrib/admin/tests.py +3 −27 Original line number Diff line number Diff line import os from unittest import SkipTest from django.contrib.staticfiles.testing import StaticLiveServerTestCase from django.test import modify_settings, tag from django.utils.module_loading import import_string from django.test import modify_settings from django.test.selenium import SeleniumTestCase from django.utils.translation import ugettext as _ Loading @@ -14,11 +11,10 @@ class CSPMiddleware(object): return response @tag('selenium') @modify_settings( MIDDLEWARE_CLASSES={'append': 'django.contrib.admin.tests.CSPMiddleware'}, ) class AdminSeleniumWebDriverTestCase(StaticLiveServerTestCase): class AdminSeleniumTestCase(SeleniumTestCase, StaticLiveServerTestCase): available_apps = [ 'django.contrib.admin', Loading @@ -27,26 +23,6 @@ class AdminSeleniumWebDriverTestCase(StaticLiveServerTestCase): 'django.contrib.sessions', 'django.contrib.sites', ] webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver' @classmethod def setUpClass(cls): if not os.environ.get('DJANGO_SELENIUM_TESTS', False): raise SkipTest('Selenium tests not requested') try: cls.selenium = import_string(cls.webdriver_class)() except Exception as e: raise SkipTest('Selenium webdriver "%s" not installed or not ' 'operational: %s' % (cls.webdriver_class, str(e))) cls.selenium.implicitly_wait(10) # This has to be last to ensure that resources are cleaned up properly! super(AdminSeleniumWebDriverTestCase, cls).setUpClass() @classmethod def _tearDownClassInternal(cls): if hasattr(cls, 'selenium'): cls.selenium.quit() super(AdminSeleniumWebDriverTestCase, cls)._tearDownClassInternal() def wait_until(self, callback, timeout=10): """ Loading
django/test/selenium.py 0 → 100644 +73 −0 Original line number Diff line number Diff line from __future__ import unicode_literals import sys import unittest from django.test import LiveServerTestCase, tag from django.utils.module_loading import import_string from django.utils.six import with_metaclass from django.utils.text import capfirst class SeleniumTestCaseBase(type(LiveServerTestCase)): # List of browsers to dynamically create test classes for. browsers = [] # Sentinel value to differentiate browser-specific instances. browser = None def __new__(cls, name, bases, attrs): """ Dynamically create new classes and add them to the test module when multiple browsers specs are provided (e.g. --selenium=firefox,chrome). """ test_class = super(SeleniumTestCaseBase, cls).__new__(cls, name, bases, attrs) # If the test class is either browser-specific or a test base, return it. if test_class.browser or not any(name.startswith('test') and callable(value) for name, value in attrs.items()): return test_class elif test_class.browsers: # Reuse the created test class to make it browser-specific. # We can't rename it to include the browser name or create a # subclass like we do with the remaining browsers as it would # either duplicate tests or prevent pickling of its instances. first_browser = test_class.browsers[0] test_class.browser = first_browser # Create subclasses for each of the remaining browsers and expose # them through the test's module namespace. module = sys.modules[test_class.__module__] for browser in test_class.browsers[1:]: browser_test_class = cls.__new__( cls, str("%s%s" % (capfirst(browser), name)), (test_class,), {'browser': browser, '__module__': test_class.__module__} ) setattr(module, browser_test_class.__name__, browser_test_class) return test_class # If no browsers were specified, skip this class (it'll still be discovered). return unittest.skip('No browsers specified.')(test_class) @classmethod def import_webdriver(cls, browser): return import_string("selenium.webdriver.%s.webdriver.WebDriver" % browser) def create_webdriver(self): return self.import_webdriver(self.browser)() @tag('selenium') class SeleniumTestCase(with_metaclass(SeleniumTestCaseBase, LiveServerTestCase)): @classmethod def setUpClass(cls): cls.selenium = cls.create_webdriver() cls.selenium.implicitly_wait(10) super(SeleniumTestCase, cls).setUpClass() @classmethod def _tearDownClassInternal(cls): # quit() the WebDriver before attempting to terminate and join the # single-threaded LiveServerThread to avoid a dead lock if the browser # kept a connection alive. if hasattr(cls, 'selenium'): cls.selenium.quit() super(SeleniumTestCase, cls)._tearDownClassInternal()
docs/internals/contributing/writing-code/unit-tests.txt +9 −5 Original line number Diff line number Diff line Loading @@ -119,16 +119,20 @@ Going beyond that, you can specify an individual test method like this:: Running the Selenium tests -------------------------- Some tests require Selenium and a Web browser (Firefox, Google Chrome, or Internet Explorer). To allow those tests to be run rather than skipped, you must install the selenium_ package into your Python path and run the tests with the ``--selenium`` option:: Some tests require Selenium and a Web browser. To run these tests, you must install the selenium_ package and run the tests with the ``--selenium=<BROWSERS>`` option. For example, if you have Firefox and Google Chrome installed:: $ ./runtests.py --settings=test_sqlite --selenium admin_inlines $ ./runtests.py --selenium=firefox,chrome See the `selenium.webdriver`_ package for the list of available browsers. Specifying ``--selenium`` automatically sets ``--tags=selenium`` to run only the tests that require selenium. .. _selenium.webdriver: https://github.com/SeleniumHQ/selenium/tree/master/py/selenium/webdriver .. _running-unit-tests-dependencies: Running all the tests Loading
tests/admin_changelist/tests.py +3 −12 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ from django.contrib import admin from django.contrib.admin.models import LogEntry from django.contrib.admin.options import IncorrectLookupParameters from django.contrib.admin.templatetags.admin_list import pagination from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase from django.contrib.admin.tests import AdminSeleniumTestCase from django.contrib.admin.views.main import ALL_VAR, SEARCH_VAR, ChangeList from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType Loading Loading @@ -882,10 +882,9 @@ class AdminLogNodeTestCase(TestCase): @override_settings(ROOT_URLCONF='admin_changelist.urls') class SeleniumFirefoxTests(AdminSeleniumWebDriverTestCase): class SeleniumTests(AdminSeleniumTestCase): available_apps = ['admin_changelist'] + AdminSeleniumWebDriverTestCase.available_apps webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver' available_apps = ['admin_changelist'] + AdminSeleniumTestCase.available_apps def setUp(self): User.objects.create_superuser(username='super', password='secret', email=None) Loading Loading @@ -915,11 +914,3 @@ class SeleniumFirefoxTests(AdminSeleniumWebDriverTestCase): '%s #result_list tbody tr:first-child .action-select' % form_id) row_selector.click() self.assertEqual(selection_indicator.text, "1 of 1 selected") class SeleniumChromeTests(SeleniumFirefoxTests): webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver' class SeleniumIETests(SeleniumFirefoxTests): webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver'