Я пытаюсь создать простой тест входа, используя Django и Selenium, но получаю 403 из-за сбоя CSRF. Я ожидаю, что промежуточное ПО добавит файл cookie в запрос GET, а затем проанализирует его на POST.Почему Selenium вызывает CSRF 403?
Вот что я проверил до сих пор:
1. Является ли печенье быть установлен на запрос GET к /accounts/login/
?
Да, печенье создается в
process_response
методом
2. Является ли куки доступны на драйвере Selenium?
Да
ipdb> self.selenium.get_cookies()
[{u'domain': u'localhost', u'name': u'csrftoken', u'value': u'DzNbEn9kZw0WZQ4OsRLouriFN5MOIQos', u'expiry': 1470691410, u'path': u'/', u'httpOnly': False, u'secure': True}]
3. Является ли печенье найден во время запроса POST?
Нет, это попытка/за исключением из
django.middleware.CsrfViewMiddleware.process_view
не удается:
try:
csrf_token = _sanitize_token(
request.COOKIES[settings.CSRF_COOKIE_NAME])
# Use same token next time
request.META['CSRF_COOKIE'] = csrf_token
except KeyError:
csrf_token = None
# Generate token and store it in the request, so it's
# available to the view.
request.META["CSRF_COOKIE"] = _get_new_csrf_key()
Код
class TestLogin(StaticLiveServerTestCase):
@classmethod
def setUpClass(cls):
cls.selenium = getattr(webdriver, settings.SELENIUM_WEBDRIVER)()
cls.selenium.maximize_window()
cls.selenium.implicitly_wait(5)
super(TestLogin, cls).setUpClass()
@classmethod
def tearDownClass(cls):
cls.selenium.quit()
super(TestLogin, cls).tearDownClass()
def test_login(self):
self.selenium.get('{}{}'.format(self.live_server_url, '/accounts/login/?next=/'))
assert "Django" in self.selenium.title
un_el = self.selenium.find_element_by_id('id_username').send_keys('the_un')
pw_el = self.selenium.find_element_by_id('id_password')
pw_el.send_keys('the_pw')
pw_el.send_keys(Keys.RETURN)
try:
WebDriverWait(self.selenium, 5).until(EC.title_contains("New Title"))
except TimeoutException as e:
msg = "Could not find 'New Title' in title. Current title: {}".format(self.selenium.title)
raise TimeoutException(msg)
finally:
self.selenium.quit()
Вопрос
Что я могу попробовать, чтобы отладить это?
Я бы использовал декоратор djangos override_settings, чтобы гарантировать, что настройки будут сброшены после выполнения теста. https://docs.djangoproject.com/ru/1.9/topics/testing/tools/#django.test.override_settings –