123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- from django.contrib.staticfiles.testing import StaticLiveServerTestCase
- from django.test import modify_settings
- from django.test.selenium import SeleniumTestCase
- from django.utils.deprecation import MiddlewareMixin
- from django.utils.translation import gettext as _
-
-
- class CSPMiddleware(MiddlewareMixin):
- """The admin's JavaScript should be compatible with CSP."""
- def process_response(self, request, response):
- response['Content-Security-Policy'] = "default-src 'self'"
- return response
-
-
- @modify_settings(MIDDLEWARE={'append': 'django.contrib.admin.tests.CSPMiddleware'})
- class AdminSeleniumTestCase(SeleniumTestCase, StaticLiveServerTestCase):
-
- available_apps = [
- 'django.contrib.admin',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.sites',
- ]
-
- def wait_until(self, callback, timeout=10):
- """
- Block the execution of the tests until the specified callback returns a
- value that is not falsy. This method can be called, for example, after
- clicking a link or submitting a form. See the other public methods that
- call this function for more details.
- """
- from selenium.webdriver.support.wait import WebDriverWait
- WebDriverWait(self.selenium, timeout).until(callback)
-
- def wait_for_popup(self, num_windows=2, timeout=10):
- """
- Block until `num_windows` are present (usually 2, but can be
- overridden in the case of pop-ups opening other pop-ups).
- """
- self.wait_until(lambda d: len(d.window_handles) == num_windows, timeout)
-
- def wait_for(self, css_selector, timeout=10):
- """
- Block until a CSS selector is found on the page.
- """
- from selenium.webdriver.common.by import By
- from selenium.webdriver.support import expected_conditions as ec
- self.wait_until(
- ec.presence_of_element_located((By.CSS_SELECTOR, css_selector)),
- timeout
- )
-
- def wait_for_text(self, css_selector, text, timeout=10):
- """
- Block until the text is found in the CSS selector.
- """
- from selenium.webdriver.common.by import By
- from selenium.webdriver.support import expected_conditions as ec
- self.wait_until(
- ec.text_to_be_present_in_element(
- (By.CSS_SELECTOR, css_selector), text),
- timeout
- )
-
- def wait_for_value(self, css_selector, text, timeout=10):
- """
- Block until the value is found in the CSS selector.
- """
- from selenium.webdriver.common.by import By
- from selenium.webdriver.support import expected_conditions as ec
- self.wait_until(
- ec.text_to_be_present_in_element_value(
- (By.CSS_SELECTOR, css_selector), text),
- timeout
- )
-
- def wait_until_visible(self, css_selector, timeout=10):
- """
- Block until the element described by the CSS selector is visible.
- """
- from selenium.webdriver.common.by import By
- from selenium.webdriver.support import expected_conditions as ec
- self.wait_until(
- ec.visibility_of_element_located((By.CSS_SELECTOR, css_selector)),
- timeout
- )
-
- def wait_until_invisible(self, css_selector, timeout=10):
- """
- Block until the element described by the CSS selector is invisible.
- """
- from selenium.webdriver.common.by import By
- from selenium.webdriver.support import expected_conditions as ec
- self.wait_until(
- ec.invisibility_of_element_located((By.CSS_SELECTOR, css_selector)),
- timeout
- )
-
- def wait_page_loaded(self):
- """
- Block until page has started to load.
- """
- from selenium.common.exceptions import TimeoutException
- try:
- # Wait for the next page to be loaded
- self.wait_for('body')
- except TimeoutException:
- # IE7 occasionally returns an error "Internet Explorer cannot
- # display the webpage" and doesn't load the next page. We just
- # ignore it.
- pass
-
- def admin_login(self, username, password, login_url='/admin/'):
- """
- Log in to the admin.
- """
- self.selenium.get('%s%s' % (self.live_server_url, login_url))
- username_input = self.selenium.find_element_by_name('username')
- username_input.send_keys(username)
- password_input = self.selenium.find_element_by_name('password')
- password_input.send_keys(password)
- login_text = _('Log in')
- self.selenium.find_element_by_xpath(
- '//input[@value="%s"]' % login_text).click()
- self.wait_page_loaded()
-
- def get_css_value(self, selector, attribute):
- """
- Return the value for the CSS attribute of a DOM element specified by
- the given selector. Uses the jQuery that ships with Django.
- """
- return self.selenium.execute_script(
- 'return django.jQuery("%s").css("%s")' % (selector, attribute))
-
- def get_select_option(self, selector, value):
- """
- Return the <OPTION> with the value `value` inside the <SELECT> widget
- identified by the CSS selector `selector`.
- """
- from selenium.common.exceptions import NoSuchElementException
- options = self.selenium.find_elements_by_css_selector('%s > option' % selector)
- for option in options:
- if option.get_attribute('value') == value:
- return option
- raise NoSuchElementException('Option "%s" not found in "%s"' % (value, selector))
-
- def _assertOptionsValues(self, options_selector, values):
- if values:
- options = self.selenium.find_elements_by_css_selector(options_selector)
- actual_values = []
- for option in options:
- actual_values.append(option.get_attribute('value'))
- self.assertEqual(values, actual_values)
- else:
- # Prevent the `find_elements_by_css_selector` call from blocking
- # if the selector doesn't match any options as we expect it
- # to be the case.
- with self.disable_implicit_wait():
- self.wait_until(
- lambda driver: not driver.find_elements_by_css_selector(options_selector)
- )
-
- def assertSelectOptions(self, selector, values):
- """
- Assert that the <SELECT> widget identified by `selector` has the
- options with the given `values`.
- """
- self._assertOptionsValues("%s > option" % selector, values)
-
- def assertSelectedOptions(self, selector, values):
- """
- Assert that the <SELECT> widget identified by `selector` has the
- selected options with the given `values`.
- """
- self._assertOptionsValues("%s > option:checked" % selector, values)
-
- def has_css_class(self, selector, klass):
- """
- Return True if the element identified by `selector` has the CSS class
- `klass`.
- """
- return (self.selenium.find_element_by_css_selector(selector)
- .get_attribute('class').find(klass) != -1)
|