diff --git a/AUTHORS b/AUTHORS index 4a09def5ad9..f9c90f9359b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -19,6 +19,7 @@ answer newbie questions, and generally made Django that much better: ajs Akis Kesoglou Aksel Ethem + Akshesh Doshi alang@bright-green.com Alasdair Nicol Albert Wang diff --git a/django/contrib/admin/tests.py b/django/contrib/admin/tests.py index 25610eb1732..20292c5dc3f 100644 --- a/django/contrib/admin/tests.py +++ b/django/contrib/admin/tests.py @@ -1,9 +1,6 @@ -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 _ @@ -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', @@ -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): """ diff --git a/django/test/selenium.py b/django/test/selenium.py new file mode 100644 index 00000000000..0f9296f7a92 --- /dev/null +++ b/django/test/selenium.py @@ -0,0 +1,73 @@ +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() diff --git a/docs/internals/contributing/writing-code/unit-tests.txt b/docs/internals/contributing/writing-code/unit-tests.txt index 37973261f4c..2cbbd30dd48 100644 --- a/docs/internals/contributing/writing-code/unit-tests.txt +++ b/docs/internals/contributing/writing-code/unit-tests.txt @@ -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=`` 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 diff --git a/tests/admin_changelist/tests.py b/tests/admin_changelist/tests.py index c61954ce5b2..505c9817680 100644 --- a/tests/admin_changelist/tests.py +++ b/tests/admin_changelist/tests.py @@ -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 @@ -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) @@ -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' diff --git a/tests/admin_inlines/tests.py b/tests/admin_inlines/tests.py index 7ea08d1a40b..9a3dc4888a2 100644 --- a/tests/admin_inlines/tests.py +++ b/tests/admin_inlines/tests.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from django.contrib.admin import ModelAdmin, TabularInline from django.contrib.admin.helpers import InlineAdminForm -from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase +from django.contrib.admin.tests import AdminSeleniumTestCase from django.contrib.auth.models import Permission, User from django.contrib.contenttypes.models import ContentType from django.test import RequestFactory, TestCase, override_settings @@ -688,10 +688,9 @@ class TestInlinePermissions(TestCase): @override_settings(ROOT_URLCONF='admin_inlines.urls') -class SeleniumFirefoxTests(AdminSeleniumWebDriverTestCase): +class SeleniumTests(AdminSeleniumTestCase): - available_apps = ['admin_inlines'] + AdminSeleniumWebDriverTestCase.available_apps - webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver' + available_apps = ['admin_inlines'] + AdminSeleniumTestCase.available_apps def setUp(self): User.objects.create_superuser(username='super', password='secret', email='super@example.com') @@ -871,11 +870,3 @@ class SeleniumFirefoxTests(AdminSeleniumWebDriverTestCase): self.wait_until_visible(field_name) hide_links[hide_index].click() self.wait_until_invisible(field_name) - - -class SeleniumChromeTests(SeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver' - - -class SeleniumIETests(SeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver' diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index 02ee00b56c0..a6b77dd44be 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -13,7 +13,7 @@ from django.contrib.admin.models import ADDITION, DELETION, LogEntry from django.contrib.admin.options import TO_FIELD_VAR from django.contrib.admin.templatetags.admin_static import static from django.contrib.admin.templatetags.admin_urls import add_preserved_filters -from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase +from django.contrib.admin.tests import AdminSeleniumTestCase from django.contrib.admin.utils import quote from django.contrib.admin.views.main import IS_POPUP_VAR from django.contrib.auth import REDIRECT_FIELD_NAME, get_permission_codename @@ -4117,10 +4117,9 @@ class PrePopulatedTest(TestCase): @override_settings(ROOT_URLCONF='admin_views.urls') -class SeleniumAdminViewsFirefoxTests(AdminSeleniumWebDriverTestCase): +class SeleniumTests(AdminSeleniumTestCase): - available_apps = ['admin_views'] + AdminSeleniumWebDriverTestCase.available_apps - webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver' + available_apps = ['admin_views'] + AdminSeleniumTestCase.available_apps def setUp(self): self.superuser = User.objects.create_superuser(username='super', password='secret', email='super@example.com') @@ -4443,14 +4442,6 @@ class SeleniumAdminViewsFirefoxTests(AdminSeleniumWebDriverTestCase): self.assertEqual(select.first_selected_option.get_attribute('value'), '') -class SeleniumAdminViewsChromeTests(SeleniumAdminViewsFirefoxTests): - webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver' - - -class SeleniumAdminViewsIETests(SeleniumAdminViewsFirefoxTests): - webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver' - - @override_settings(ROOT_URLCONF='admin_views.urls') class ReadonlyTest(AdminFieldExtractionMixin, TestCase): diff --git a/tests/admin_widgets/tests.py b/tests/admin_widgets/tests.py index 3258fdbba1d..18d3f7b7e13 100644 --- a/tests/admin_widgets/tests.py +++ b/tests/admin_widgets/tests.py @@ -11,7 +11,7 @@ from django import forms from django.conf import settings from django.contrib import admin from django.contrib.admin import widgets -from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase +from django.contrib.admin.tests import AdminSeleniumTestCase from django.contrib.auth.models import User from django.core.files.storage import default_storage from django.core.files.uploadedfile import SimpleUploadedFile @@ -39,11 +39,6 @@ class TestDataMixin(object): models.Car.objects.create(owner=cls.u2, make='BMW', model='M3') -class SeleniumDataMixin(object): - def setUp(self): - self.u1 = User.objects.create_superuser(username='super', password='secret', email='super@example.com') - - class AdminFormfieldForDBFieldTests(SimpleTestCase): """ Tests for correct behavior of ModelAdmin.formfield_for_dbfield @@ -619,10 +614,15 @@ class RelatedFieldWidgetWrapperTests(SimpleTestCase): @override_settings(ROOT_URLCONF='admin_widgets.urls') -class DateTimePickerSeleniumFirefoxTests(SeleniumDataMixin, AdminSeleniumWebDriverTestCase): +class AdminWidgetSeleniumTestCase(AdminSeleniumTestCase): - available_apps = ['admin_widgets'] + AdminSeleniumWebDriverTestCase.available_apps - webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver' + available_apps = ['admin_widgets'] + AdminSeleniumTestCase.available_apps + + def setUp(self): + self.u1 = User.objects.create_superuser(username='super', password='secret', email='super@example.com') + + +class DateTimePickerSeleniumTests(AdminWidgetSeleniumTestCase): def test_show_hide_date_time_picker_widgets(self): """ @@ -786,19 +786,9 @@ class DateTimePickerSeleniumFirefoxTests(SeleniumDataMixin, AdminSeleniumWebDriv self.wait_for_text('#calendarin0 caption', expected_caption) -class DateTimePickerSeleniumChromeTests(DateTimePickerSeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver' - - -class DateTimePickerSeleniumIETests(DateTimePickerSeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver' - - @skipIf(pytz is None, "this test requires pytz") -@override_settings(ROOT_URLCONF='admin_widgets.urls', TIME_ZONE='Asia/Singapore') -class DateTimePickerShortcutsSeleniumFirefoxTests(SeleniumDataMixin, AdminSeleniumWebDriverTestCase): - available_apps = ['admin_widgets'] + AdminSeleniumWebDriverTestCase.available_apps - webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver' +@override_settings(TIME_ZONE='Asia/Singapore') +class DateTimePickerShortcutsSeleniumTests(AdminWidgetSeleniumTestCase): def test_date_time_picker_shortcuts(self): """ @@ -853,37 +843,17 @@ class DateTimePickerShortcutsSeleniumFirefoxTests(SeleniumDataMixin, AdminSeleni self.assertLess(member.birthdate, now + error_margin) -class DateTimePickerShortcutsSeleniumChromeTests(DateTimePickerShortcutsSeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver' - - -class DateTimePickerShortcutsSeleniumIETests(DateTimePickerShortcutsSeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver' - - # The above tests run with Asia/Singapore which are on the positive side of # UTC. Here we test with a timezone on the negative side. @override_settings(TIME_ZONE='US/Eastern') -class DateTimePickerAltTimezoneSeleniumFirefoxTests(DateTimePickerShortcutsSeleniumFirefoxTests): +class DateTimePickerAltTimezoneSeleniumTests(DateTimePickerShortcutsSeleniumTests): pass -class DateTimePickerAltTimezoneSeleniumChromeTests(DateTimePickerAltTimezoneSeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver' - - -class DateTimePickerAltTimezoneSeleniumIETests(DateTimePickerAltTimezoneSeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver' - - -@override_settings(ROOT_URLCONF='admin_widgets.urls') -class HorizontalVerticalFilterSeleniumFirefoxTests(SeleniumDataMixin, AdminSeleniumWebDriverTestCase): - - available_apps = ['admin_widgets'] + AdminSeleniumWebDriverTestCase.available_apps - webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver' +class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase): def setUp(self): - super(HorizontalVerticalFilterSeleniumFirefoxTests, self).setUp() + super(HorizontalVerticalFilterSeleniumTests, self).setUp() self.lisa = models.Student.objects.create(name='Lisa') self.john = models.Student.objects.create(name='John') self.bob = models.Student.objects.create(name='Bob') @@ -1168,21 +1138,10 @@ class HorizontalVerticalFilterSeleniumFirefoxTests(SeleniumDataMixin, AdminSelen self.assertEqual(options_len, 2) -class HorizontalVerticalFilterSeleniumChromeTests(HorizontalVerticalFilterSeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver' - - -class HorizontalVerticalFilterSeleniumIETests(HorizontalVerticalFilterSeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver' - - -@override_settings(ROOT_URLCONF='admin_widgets.urls') -class AdminRawIdWidgetSeleniumFirefoxTests(SeleniumDataMixin, AdminSeleniumWebDriverTestCase): - available_apps = ['admin_widgets'] + AdminSeleniumWebDriverTestCase.available_apps - webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver' +class AdminRawIdWidgetSeleniumTests(AdminWidgetSeleniumTestCase): def setUp(self): - super(AdminRawIdWidgetSeleniumFirefoxTests, self).setUp() + super(AdminRawIdWidgetSeleniumTests, self).setUp() models.Band.objects.create(id=42, name='Bogey Blues') models.Band.objects.create(id=98, name='Green Potatoes') @@ -1263,18 +1222,7 @@ class AdminRawIdWidgetSeleniumFirefoxTests(SeleniumDataMixin, AdminSeleniumWebDr self.wait_for_value('#id_supporting_bands', '42,98') -class AdminRawIdWidgetSeleniumChromeTests(AdminRawIdWidgetSeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver' - - -class AdminRawIdWidgetSeleniumIETests(AdminRawIdWidgetSeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver' - - -@override_settings(ROOT_URLCONF='admin_widgets.urls') -class RelatedFieldWidgetSeleniumFirefoxTests(SeleniumDataMixin, AdminSeleniumWebDriverTestCase): - available_apps = ['admin_widgets'] + AdminSeleniumWebDriverTestCase.available_apps - webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver' +class RelatedFieldWidgetSeleniumTests(AdminWidgetSeleniumTestCase): def test_ForeignKey_using_to_field(self): self.admin_login(username='super', password='secret', login_url='/') @@ -1321,11 +1269,3 @@ class RelatedFieldWidgetSeleniumFirefoxTests(SeleniumDataMixin, AdminSeleniumWeb profiles = models.Profile.objects.all() self.assertEqual(len(profiles), 1) self.assertEqual(profiles[0].user.username, username_value) - - -class RelatedFieldWidgetSeleniumChromeTests(RelatedFieldWidgetSeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver' - - -class RelatedFieldWidgetSeleniumIETests(RelatedFieldWidgetSeleniumFirefoxTests): - webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver' diff --git a/tests/forms_tests/tests/test_widgets.py b/tests/forms_tests/tests/test_widgets.py index 965f8f5493a..261cb4bc38d 100644 --- a/tests/forms_tests/tests/test_widgets.py +++ b/tests/forms_tests/tests/test_widgets.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase +from django.contrib.admin.tests import AdminSeleniumTestCase from django.forms import ( CheckboxSelectMultiple, ClearableFileInput, RadioSelect, TextInput, ) @@ -161,9 +161,9 @@ beatle J R Ringo False""") @override_settings(ROOT_URLCONF='forms_tests.urls') -class LiveWidgetTests(AdminSeleniumWebDriverTestCase): +class LiveWidgetTests(AdminSeleniumTestCase): - available_apps = ['forms_tests'] + AdminSeleniumWebDriverTestCase.available_apps + available_apps = ['forms_tests'] + AdminSeleniumTestCase.available_apps def test_textarea_trailing_newlines(self): """ diff --git a/tests/runtests.py b/tests/runtests.py index 2fa73e74383..802922a7ee0 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -1,4 +1,5 @@ #!/usr/bin/env python +import argparse import atexit import copy import os @@ -7,7 +8,6 @@ import subprocess import sys import tempfile import warnings -from argparse import ArgumentParser import django from django.apps import apps @@ -15,6 +15,7 @@ from django.conf import settings from django.db import connection, connections from django.test import TestCase, TransactionTestCase from django.test.runner import default_test_processes +from django.test.selenium import SeleniumTestCaseBase from django.test.utils import get_runner from django.utils import six from django.utils._os import upath @@ -233,6 +234,20 @@ def actual_test_processes(parallel): return parallel +class ActionSelenium(argparse.Action): + """ + Validate the comma-separated list of requested browsers. + """ + def __call__(self, parser, namespace, values, option_string=None): + browsers = values.split(',') + for browser in browsers: + try: + SeleniumTestCaseBase.import_webdriver(browser) + except ImportError: + raise argparse.ArgumentError(self, "Selenium browser specification '%s' is not valid." % browser) + setattr(namespace, self.dest, browsers) + + def django_tests(verbosity, interactive, failfast, keepdb, reverse, test_labels, debug_sql, parallel, tags, exclude_tags): state = setup(verbosity, test_labels, parallel) @@ -360,7 +375,7 @@ def paired_tests(paired_test, options, test_labels, parallel): if __name__ == "__main__": - parser = ArgumentParser(description="Run the Django test suite.") + parser = argparse.ArgumentParser(description="Run the Django test suite.") parser.add_argument('modules', nargs='*', metavar='module', help='Optional path(s) to test modules; e.g. "i18n" or ' '"i18n.tests.TranslationTests.test_lazy_objects".') @@ -396,8 +411,8 @@ if __name__ == "__main__": 'LiveServerTestCase) is expected to run from. The default value ' 'is localhost:8081-8179.') parser.add_argument( - '--selenium', action='store_true', dest='selenium', default=False, - help='Run only the Selenium tests (equivalent to "--tag selenium").') + '--selenium', dest='selenium', action=ActionSelenium, metavar='BROWSERS', + help='A comma-separated list of browsers to run the Selenium tests against.') parser.add_argument( '--debug-sql', action='store_true', dest='debug_sql', default=False, help='Turn on the SQL query logger within tests.') @@ -438,11 +453,11 @@ if __name__ == "__main__": os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = options.liveserver if options.selenium: - os.environ['DJANGO_SELENIUM_TESTS'] = '1' if not options.tags: options.tags = ['selenium'] elif 'selenium' not in options.tags: options.tags.append('selenium') + SeleniumTestCaseBase.browsers = options.selenium if options.bisect: bisect_tests(options.bisect, options, options.modules, options.parallel) diff --git a/tests/view_tests/tests/test_i18n.py b/tests/view_tests/tests/test_i18n.py index ae39f344215..a957d32d962 100644 --- a/tests/view_tests/tests/test_i18n.py +++ b/tests/view_tests/tests/test_i18n.py @@ -3,19 +3,16 @@ from __future__ import unicode_literals import gettext import json -import os -import unittest from os import path from django.conf import settings from django.test import ( - LiveServerTestCase, SimpleTestCase, TestCase, modify_settings, - override_settings, tag, + SimpleTestCase, TestCase, modify_settings, override_settings, ) +from django.test.selenium import SeleniumTestCase from django.urls import reverse from django.utils import six from django.utils._os import upath -from django.utils.module_loading import import_string from django.utils.translation import LANGUAGE_SESSION_KEY, override from ..urls import locale_dir @@ -265,35 +262,14 @@ class JsI18NTestsMultiPackage(SimpleTestCase): 'este texto de app3 debe ser traducido') -skip_selenium = not os.environ.get('DJANGO_SELENIUM_TESTS', False) - - -@unittest.skipIf(skip_selenium, 'Selenium tests not requested') -@tag('selenium') @override_settings(ROOT_URLCONF='view_tests.urls') -class JavascriptI18nTests(LiveServerTestCase): +class JavascriptI18nTests(SeleniumTestCase): # The test cases use fixtures & translations from these apps. available_apps = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'view_tests', ] - webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver' - - @classmethod - def setUpClass(cls): - try: - cls.selenium = import_string(cls.webdriver_class)() - except Exception as e: - raise unittest.SkipTest('Selenium webdriver "%s" not installed or ' - 'not operational: %s' % (cls.webdriver_class, str(e))) - cls.selenium.implicitly_wait(10) - super(JavascriptI18nTests, cls).setUpClass() - - @classmethod - def tearDownClass(cls): - cls.selenium.quit() - super(JavascriptI18nTests, cls).tearDownClass() @override_settings(LANGUAGE_CODE='de') def test_javascript_gettext(self): @@ -321,11 +297,3 @@ class JavascriptI18nTests(LiveServerTestCase): self.assertEqual(elem.text, 'il faut traduire cette chaîne de caractères de app1') elem = self.selenium.find_element_by_id('app2string') self.assertEqual(elem.text, 'il faut traduire cette chaîne de caractères de app2') - - -class JavascriptI18nChromeTests(JavascriptI18nTests): - webdriver_class = 'selenium.webdriver.chrome.webdriver.WebDriver' - - -class JavascriptI18nIETests(JavascriptI18nTests): - webdriver_class = 'selenium.webdriver.ie.webdriver.WebDriver'