Аутентификация пользователя Django не работает в тестах selenium
Я пишу тесты для своего приложения djangocms, впервые используя selenium для репликации браузера/пользователя. Я пытаюсь протестировать страницу входа, пользователь просто заполняет имя пользователя & пароль, но я не могу заставить authenticate работать в тестах selenium. Я могу войти в систему через сайт самостоятельно & я даже могу использовать authenticate в тестовом блоке кода, но selenium не работает, какие-нибудь советы? Все, что я читал до сих пор, касалось только того, что пароль пользователя не хэшируется при сохранении, что я и делаю, поэтому у меня нет подсказки. Я знаю, что учетные данные верны, пользователь существует, & пароль хэшируется в базе данных. Это также единственный тест, который я запускаю, так что нет никаких шансов, что другие тесты повлияют на него. Я также знаю, что после отключения 'headless' поля ввода заполняются правильно selenium, просто не происходит аутентификация. Также, не думаю, что это имеет значение, но кнопка submit запускает метод javascript в vue.js, который делает вызов axios (версия ajax в vue). Но я знаю, что весь JS-код работает, иначе сообщение не появилось бы на странице.
Здесь я создаю пользователя в setup
def create_user(role='competitor', username=None, email='test@yahoo.com', password='password', superuser=False):
# if not given a username, we generate a random string since username's have to be unique
random_string = string.ascii_letters + string.digits
if not username:
username = 'username_' + (''.join(
(random.choice(random_string) for i in range(10))
))
group, created = Group.objects.get_or_create(name=role)
new_user = User(username=username, email=email)
new_user.set_password(password)
if superuser:
new_user.is_superuser = True
if role == 'admin':
new_user.is_staff = True
new_user.save()
group.user_set.add(new_user)
return new_user
Вот фактические тесты. Обратите внимание, что authenticate работает здесь, но не работает в браузере с selenium
import time
from django.contrib.auth.models import User
from tests.utils.petrobowl_model_utils import create_user
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from django.test import LiveServerTestCase
from selenium import webdriver
from django.test.client import RequestFactory
request = RequestFactory()
class PetrobowlLoginTemplateTests(LiveServerTestCase):
# we set up our driver before any tests start
def setUp(self):
self.user = create_user(username='test_user', password='password')
time.sleep(2)
options = webdriver.ChromeOptions()
options.add_argument('headless')
self.driver = webdriver.Chrome(ChromeDriverManager().install(), options=options)
# here we test the login page works, and we can log in successfully
def test_login_form_works(self):
self.driver.get("http://127.0.0.1:8000/user/login/")
assert 'Login' in self.driver.page_source
username_input = self.driver.find_element(By.ID, "username_confirmation")
username_input.send_keys(self.user.username)
password_input = self.driver.find_element(By.ID, "password")
password_input.send_keys('password')
submit = self.driver.find_element(By.ID, "login_button")
# this works for some reason, exact same credentials.
from django.contrib.auth import authenticate
test = authenticate(request, username='test_user', password='password')
print('test = ', test)
submit.click()
time.sleep(1)
# these top two should fail & bottom two should pass, but the username/password never authenticates
assert 'Username or Password is incorrect' in self.driver.page_source
assert 'Login' in self.driver.page_source
assert 'Welcome to Petrobowl' in self.driver.page_source
assert 'Successfully logged in' in self.driver.page_source
В представлении он просто захватывает данные, прогоняет их через форму и терпит неудачу здесь:
user = authenticate(request, username=form_data['username_confirmation'], password=form_data['password'])
Когда эта строка не работает, она передает обратно на страницу 'Username or Password is incorrect', поэтому я знаю, что сбой именно там. Есть предложения?
Для всех, кто столкнулся с подобной проблемой, я нашел решение проблемы. Selenium не мог войти в систему, потому что он использовал реальную базу данных & сервера & а не тестовую базу данных. Мне пришлось изменить строку self.driver.get чуть ниже test_login_form_works на следующую. Это заставило Selenium использовать порт, на котором он должен работать, и использовать тестовую базу данных
self.driver.get('%s%s' % (self.live_server_url, '/user/login/'))