Fixed #25364 -- Added generic way to test on all browsers supported by selenium.
Browser names should be passed as a comma separated list to the --selenium flag. Thanks Tim Graham, Simon Charette and Moritz Sichert for review and discussion.
This commit is contained in:
parent
93a135d111
commit
44c0ecdd92
1
AUTHORS
1
AUTHORS
|
@ -19,6 +19,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
ajs <adi@sieker.info>
|
ajs <adi@sieker.info>
|
||||||
Akis Kesoglou <akiskesoglou@gmail.com>
|
Akis Kesoglou <akiskesoglou@gmail.com>
|
||||||
Aksel Ethem <aksel.ethem@gmail.com>
|
Aksel Ethem <aksel.ethem@gmail.com>
|
||||||
|
Akshesh Doshi <aksheshdoshi+django@gmail.com>
|
||||||
alang@bright-green.com
|
alang@bright-green.com
|
||||||
Alasdair Nicol <http://al.sdair.co.uk/>
|
Alasdair Nicol <http://al.sdair.co.uk/>
|
||||||
Albert Wang <aywang31@gmail.com>
|
Albert Wang <aywang31@gmail.com>
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
import os
|
|
||||||
from unittest import SkipTest
|
|
||||||
|
|
||||||
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
|
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
|
||||||
from django.test import modify_settings, tag
|
from django.test import modify_settings
|
||||||
from django.utils.module_loading import import_string
|
from django.test.selenium import SeleniumTestCase
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,11 +11,10 @@ class CSPMiddleware(object):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
@tag('selenium')
|
|
||||||
@modify_settings(
|
@modify_settings(
|
||||||
MIDDLEWARE_CLASSES={'append': 'django.contrib.admin.tests.CSPMiddleware'},
|
MIDDLEWARE_CLASSES={'append': 'django.contrib.admin.tests.CSPMiddleware'},
|
||||||
)
|
)
|
||||||
class AdminSeleniumWebDriverTestCase(StaticLiveServerTestCase):
|
class AdminSeleniumTestCase(SeleniumTestCase, StaticLiveServerTestCase):
|
||||||
|
|
||||||
available_apps = [
|
available_apps = [
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
|
@ -27,26 +23,6 @@ class AdminSeleniumWebDriverTestCase(StaticLiveServerTestCase):
|
||||||
'django.contrib.sessions',
|
'django.contrib.sessions',
|
||||||
'django.contrib.sites',
|
'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):
|
def wait_until(self, callback, timeout=10):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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()
|
|
@ -119,16 +119,20 @@ Going beyond that, you can specify an individual test method like this::
|
||||||
Running the Selenium tests
|
Running the Selenium tests
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
Some tests require Selenium and a Web browser (Firefox, Google Chrome, or
|
Some tests require Selenium and a Web browser. To run these tests, you must
|
||||||
Internet Explorer). To allow those tests to be run rather than skipped, you must
|
install the selenium_ package and run the tests with the
|
||||||
install the selenium_ package into your Python path and run the tests with the
|
``--selenium=<BROWSERS>`` option. For example, if you have Firefox and Google
|
||||||
``--selenium`` option::
|
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
|
Specifying ``--selenium`` automatically sets ``--tags=selenium`` to run only
|
||||||
the tests that require selenium.
|
the tests that require selenium.
|
||||||
|
|
||||||
|
.. _selenium.webdriver: https://github.com/SeleniumHQ/selenium/tree/master/py/selenium/webdriver
|
||||||
|
|
||||||
.. _running-unit-tests-dependencies:
|
.. _running-unit-tests-dependencies:
|
||||||
|
|
||||||
Running all the tests
|
Running all the tests
|
||||||
|
|
|
@ -6,7 +6,7 @@ from django.contrib import admin
|
||||||
from django.contrib.admin.models import LogEntry
|
from django.contrib.admin.models import LogEntry
|
||||||
from django.contrib.admin.options import IncorrectLookupParameters
|
from django.contrib.admin.options import IncorrectLookupParameters
|
||||||
from django.contrib.admin.templatetags.admin_list import pagination
|
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.admin.views.main import ALL_VAR, SEARCH_VAR, ChangeList
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
@ -882,10 +882,9 @@ class AdminLogNodeTestCase(TestCase):
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='admin_changelist.urls')
|
@override_settings(ROOT_URLCONF='admin_changelist.urls')
|
||||||
class SeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
|
class SeleniumTests(AdminSeleniumTestCase):
|
||||||
|
|
||||||
available_apps = ['admin_changelist'] + AdminSeleniumWebDriverTestCase.available_apps
|
available_apps = ['admin_changelist'] + AdminSeleniumTestCase.available_apps
|
||||||
webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver'
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
User.objects.create_superuser(username='super', password='secret', email=None)
|
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)
|
'%s #result_list tbody tr:first-child .action-select' % form_id)
|
||||||
row_selector.click()
|
row_selector.click()
|
||||||
self.assertEqual(selection_indicator.text, "1 of 1 selected")
|
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'
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.contrib.admin import ModelAdmin, TabularInline
|
from django.contrib.admin import ModelAdmin, TabularInline
|
||||||
from django.contrib.admin.helpers import InlineAdminForm
|
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.auth.models import Permission, User
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.test import RequestFactory, TestCase, override_settings
|
from django.test import RequestFactory, TestCase, override_settings
|
||||||
|
@ -688,10 +688,9 @@ class TestInlinePermissions(TestCase):
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='admin_inlines.urls')
|
@override_settings(ROOT_URLCONF='admin_inlines.urls')
|
||||||
class SeleniumFirefoxTests(AdminSeleniumWebDriverTestCase):
|
class SeleniumTests(AdminSeleniumTestCase):
|
||||||
|
|
||||||
available_apps = ['admin_inlines'] + AdminSeleniumWebDriverTestCase.available_apps
|
available_apps = ['admin_inlines'] + AdminSeleniumTestCase.available_apps
|
||||||
webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver'
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
User.objects.create_superuser(username='super', password='secret', email='super@example.com')
|
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)
|
self.wait_until_visible(field_name)
|
||||||
hide_links[hide_index].click()
|
hide_links[hide_index].click()
|
||||||
self.wait_until_invisible(field_name)
|
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'
|
|
||||||
|
|
|
@ -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.options import TO_FIELD_VAR
|
||||||
from django.contrib.admin.templatetags.admin_static import static
|
from django.contrib.admin.templatetags.admin_static import static
|
||||||
from django.contrib.admin.templatetags.admin_urls import add_preserved_filters
|
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.utils import quote
|
||||||
from django.contrib.admin.views.main import IS_POPUP_VAR
|
from django.contrib.admin.views.main import IS_POPUP_VAR
|
||||||
from django.contrib.auth import REDIRECT_FIELD_NAME, get_permission_codename
|
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')
|
@override_settings(ROOT_URLCONF='admin_views.urls')
|
||||||
class SeleniumAdminViewsFirefoxTests(AdminSeleniumWebDriverTestCase):
|
class SeleniumTests(AdminSeleniumTestCase):
|
||||||
|
|
||||||
available_apps = ['admin_views'] + AdminSeleniumWebDriverTestCase.available_apps
|
available_apps = ['admin_views'] + AdminSeleniumTestCase.available_apps
|
||||||
webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver'
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.superuser = User.objects.create_superuser(username='super', password='secret', email='super@example.com')
|
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'), '')
|
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')
|
@override_settings(ROOT_URLCONF='admin_views.urls')
|
||||||
class ReadonlyTest(AdminFieldExtractionMixin, TestCase):
|
class ReadonlyTest(AdminFieldExtractionMixin, TestCase):
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ from django import forms
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.admin import widgets
|
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.contrib.auth.models import User
|
||||||
from django.core.files.storage import default_storage
|
from django.core.files.storage import default_storage
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
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')
|
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):
|
class AdminFormfieldForDBFieldTests(SimpleTestCase):
|
||||||
"""
|
"""
|
||||||
Tests for correct behavior of ModelAdmin.formfield_for_dbfield
|
Tests for correct behavior of ModelAdmin.formfield_for_dbfield
|
||||||
|
@ -619,10 +614,15 @@ class RelatedFieldWidgetWrapperTests(SimpleTestCase):
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='admin_widgets.urls')
|
@override_settings(ROOT_URLCONF='admin_widgets.urls')
|
||||||
class DateTimePickerSeleniumFirefoxTests(SeleniumDataMixin, AdminSeleniumWebDriverTestCase):
|
class AdminWidgetSeleniumTestCase(AdminSeleniumTestCase):
|
||||||
|
|
||||||
available_apps = ['admin_widgets'] + AdminSeleniumWebDriverTestCase.available_apps
|
available_apps = ['admin_widgets'] + AdminSeleniumTestCase.available_apps
|
||||||
webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver'
|
|
||||||
|
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):
|
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)
|
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")
|
@skipIf(pytz is None, "this test requires pytz")
|
||||||
@override_settings(ROOT_URLCONF='admin_widgets.urls', TIME_ZONE='Asia/Singapore')
|
@override_settings(TIME_ZONE='Asia/Singapore')
|
||||||
class DateTimePickerShortcutsSeleniumFirefoxTests(SeleniumDataMixin, AdminSeleniumWebDriverTestCase):
|
class DateTimePickerShortcutsSeleniumTests(AdminWidgetSeleniumTestCase):
|
||||||
available_apps = ['admin_widgets'] + AdminSeleniumWebDriverTestCase.available_apps
|
|
||||||
webdriver_class = 'selenium.webdriver.firefox.webdriver.WebDriver'
|
|
||||||
|
|
||||||
def test_date_time_picker_shortcuts(self):
|
def test_date_time_picker_shortcuts(self):
|
||||||
"""
|
"""
|
||||||
|
@ -853,37 +843,17 @@ class DateTimePickerShortcutsSeleniumFirefoxTests(SeleniumDataMixin, AdminSeleni
|
||||||
self.assertLess(member.birthdate, now + error_margin)
|
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
|
# 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.
|
# UTC. Here we test with a timezone on the negative side.
|
||||||
@override_settings(TIME_ZONE='US/Eastern')
|
@override_settings(TIME_ZONE='US/Eastern')
|
||||||
class DateTimePickerAltTimezoneSeleniumFirefoxTests(DateTimePickerShortcutsSeleniumFirefoxTests):
|
class DateTimePickerAltTimezoneSeleniumTests(DateTimePickerShortcutsSeleniumTests):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class DateTimePickerAltTimezoneSeleniumChromeTests(DateTimePickerAltTimezoneSeleniumFirefoxTests):
|
class HorizontalVerticalFilterSeleniumTests(AdminWidgetSeleniumTestCase):
|
||||||
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'
|
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(HorizontalVerticalFilterSeleniumFirefoxTests, self).setUp()
|
super(HorizontalVerticalFilterSeleniumTests, self).setUp()
|
||||||
self.lisa = models.Student.objects.create(name='Lisa')
|
self.lisa = models.Student.objects.create(name='Lisa')
|
||||||
self.john = models.Student.objects.create(name='John')
|
self.john = models.Student.objects.create(name='John')
|
||||||
self.bob = models.Student.objects.create(name='Bob')
|
self.bob = models.Student.objects.create(name='Bob')
|
||||||
|
@ -1168,21 +1138,10 @@ class HorizontalVerticalFilterSeleniumFirefoxTests(SeleniumDataMixin, AdminSelen
|
||||||
self.assertEqual(options_len, 2)
|
self.assertEqual(options_len, 2)
|
||||||
|
|
||||||
|
|
||||||
class HorizontalVerticalFilterSeleniumChromeTests(HorizontalVerticalFilterSeleniumFirefoxTests):
|
class AdminRawIdWidgetSeleniumTests(AdminWidgetSeleniumTestCase):
|
||||||
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'
|
|
||||||
|
|
||||||
def setUp(self):
|
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=42, name='Bogey Blues')
|
||||||
models.Band.objects.create(id=98, name='Green Potatoes')
|
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')
|
self.wait_for_value('#id_supporting_bands', '42,98')
|
||||||
|
|
||||||
|
|
||||||
class AdminRawIdWidgetSeleniumChromeTests(AdminRawIdWidgetSeleniumFirefoxTests):
|
class RelatedFieldWidgetSeleniumTests(AdminWidgetSeleniumTestCase):
|
||||||
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'
|
|
||||||
|
|
||||||
def test_ForeignKey_using_to_field(self):
|
def test_ForeignKey_using_to_field(self):
|
||||||
self.admin_login(username='super', password='secret', login_url='/')
|
self.admin_login(username='super', password='secret', login_url='/')
|
||||||
|
@ -1321,11 +1269,3 @@ class RelatedFieldWidgetSeleniumFirefoxTests(SeleniumDataMixin, AdminSeleniumWeb
|
||||||
profiles = models.Profile.objects.all()
|
profiles = models.Profile.objects.all()
|
||||||
self.assertEqual(len(profiles), 1)
|
self.assertEqual(len(profiles), 1)
|
||||||
self.assertEqual(profiles[0].user.username, username_value)
|
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'
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.contrib.admin.tests import AdminSeleniumWebDriverTestCase
|
from django.contrib.admin.tests import AdminSeleniumTestCase
|
||||||
from django.forms import (
|
from django.forms import (
|
||||||
CheckboxSelectMultiple, ClearableFileInput, RadioSelect, TextInput,
|
CheckboxSelectMultiple, ClearableFileInput, RadioSelect, TextInput,
|
||||||
)
|
)
|
||||||
|
@ -161,9 +161,9 @@ beatle J R Ringo False""")
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='forms_tests.urls')
|
@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):
|
def test_textarea_trailing_newlines(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
import argparse
|
||||||
import atexit
|
import atexit
|
||||||
import copy
|
import copy
|
||||||
import os
|
import os
|
||||||
|
@ -7,7 +8,6 @@ import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import warnings
|
import warnings
|
||||||
from argparse import ArgumentParser
|
|
||||||
|
|
||||||
import django
|
import django
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
|
@ -15,6 +15,7 @@ from django.conf import settings
|
||||||
from django.db import connection, connections
|
from django.db import connection, connections
|
||||||
from django.test import TestCase, TransactionTestCase
|
from django.test import TestCase, TransactionTestCase
|
||||||
from django.test.runner import default_test_processes
|
from django.test.runner import default_test_processes
|
||||||
|
from django.test.selenium import SeleniumTestCaseBase
|
||||||
from django.test.utils import get_runner
|
from django.test.utils import get_runner
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
|
@ -233,6 +234,20 @@ def actual_test_processes(parallel):
|
||||||
return 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,
|
def django_tests(verbosity, interactive, failfast, keepdb, reverse,
|
||||||
test_labels, debug_sql, parallel, tags, exclude_tags):
|
test_labels, debug_sql, parallel, tags, exclude_tags):
|
||||||
state = setup(verbosity, test_labels, parallel)
|
state = setup(verbosity, test_labels, parallel)
|
||||||
|
@ -360,7 +375,7 @@ def paired_tests(paired_test, options, test_labels, parallel):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
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',
|
parser.add_argument('modules', nargs='*', metavar='module',
|
||||||
help='Optional path(s) to test modules; e.g. "i18n" or '
|
help='Optional path(s) to test modules; e.g. "i18n" or '
|
||||||
'"i18n.tests.TranslationTests.test_lazy_objects".')
|
'"i18n.tests.TranslationTests.test_lazy_objects".')
|
||||||
|
@ -396,8 +411,8 @@ if __name__ == "__main__":
|
||||||
'LiveServerTestCase) is expected to run from. The default value '
|
'LiveServerTestCase) is expected to run from. The default value '
|
||||||
'is localhost:8081-8179.')
|
'is localhost:8081-8179.')
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--selenium', action='store_true', dest='selenium', default=False,
|
'--selenium', dest='selenium', action=ActionSelenium, metavar='BROWSERS',
|
||||||
help='Run only the Selenium tests (equivalent to "--tag selenium").')
|
help='A comma-separated list of browsers to run the Selenium tests against.')
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--debug-sql', action='store_true', dest='debug_sql', default=False,
|
'--debug-sql', action='store_true', dest='debug_sql', default=False,
|
||||||
help='Turn on the SQL query logger within tests.')
|
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
|
os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = options.liveserver
|
||||||
|
|
||||||
if options.selenium:
|
if options.selenium:
|
||||||
os.environ['DJANGO_SELENIUM_TESTS'] = '1'
|
|
||||||
if not options.tags:
|
if not options.tags:
|
||||||
options.tags = ['selenium']
|
options.tags = ['selenium']
|
||||||
elif 'selenium' not in options.tags:
|
elif 'selenium' not in options.tags:
|
||||||
options.tags.append('selenium')
|
options.tags.append('selenium')
|
||||||
|
SeleniumTestCaseBase.browsers = options.selenium
|
||||||
|
|
||||||
if options.bisect:
|
if options.bisect:
|
||||||
bisect_tests(options.bisect, options, options.modules, options.parallel)
|
bisect_tests(options.bisect, options, options.modules, options.parallel)
|
||||||
|
|
|
@ -3,19 +3,16 @@ from __future__ import unicode_literals
|
||||||
|
|
||||||
import gettext
|
import gettext
|
||||||
import json
|
import json
|
||||||
import os
|
|
||||||
import unittest
|
|
||||||
from os import path
|
from os import path
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.test import (
|
from django.test import (
|
||||||
LiveServerTestCase, SimpleTestCase, TestCase, modify_settings,
|
SimpleTestCase, TestCase, modify_settings, override_settings,
|
||||||
override_settings, tag,
|
|
||||||
)
|
)
|
||||||
|
from django.test.selenium import SeleniumTestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
from django.utils.module_loading import import_string
|
|
||||||
from django.utils.translation import LANGUAGE_SESSION_KEY, override
|
from django.utils.translation import LANGUAGE_SESSION_KEY, override
|
||||||
|
|
||||||
from ..urls import locale_dir
|
from ..urls import locale_dir
|
||||||
|
@ -265,35 +262,14 @@ class JsI18NTestsMultiPackage(SimpleTestCase):
|
||||||
'este texto de app3 debe ser traducido')
|
'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')
|
@override_settings(ROOT_URLCONF='view_tests.urls')
|
||||||
class JavascriptI18nTests(LiveServerTestCase):
|
class JavascriptI18nTests(SeleniumTestCase):
|
||||||
|
|
||||||
# The test cases use fixtures & translations from these apps.
|
# The test cases use fixtures & translations from these apps.
|
||||||
available_apps = [
|
available_apps = [
|
||||||
'django.contrib.admin', 'django.contrib.auth',
|
'django.contrib.admin', 'django.contrib.auth',
|
||||||
'django.contrib.contenttypes', 'view_tests',
|
'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')
|
@override_settings(LANGUAGE_CODE='de')
|
||||||
def test_javascript_gettext(self):
|
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')
|
self.assertEqual(elem.text, 'il faut traduire cette chaîne de caractères de app1')
|
||||||
elem = self.selenium.find_element_by_id('app2string')
|
elem = self.selenium.find_element_by_id('app2string')
|
||||||
self.assertEqual(elem.text, 'il faut traduire cette chaîne de caractères de app2')
|
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'
|
|
||||||
|
|
Loading…
Reference in New Issue