Selenium не может войти в Django LiveServerTestCase - PullRequest
1 голос
/ 18 мая 2019

Я изо всех сил пытаюсь заставить Selenium работать с моим проектом Django.Я (наконец) могу получить его на get страницах во время тестирования, но по какой-то причине я не могу получить его для входа в систему.

Это мой (очень простой) тестовый пример:

import pytest

from django.conf import settings
from django.contrib.auth import get_user_model
from django.test.client import Client

from pytest_django.live_server_helper import LiveServer
from selenium.webdriver import Remote

from users.tests.factories import UserFactory


pytestmark = pytest.mark.django_db


class TestDashboard:
    def test_site_loads(self, browser: Remote, test_server: LiveServer):
        browser.get(test_server.url)

        assert 'Welcome' in browser.title

    def test_valid_login(self, browser: Remote, test_server: LiveServer, user: settings.AUTH_USER_MODEL):
        password = 'testpassword'
        user.set_password(password)
        user.save()

        browser.get(test_server.url + '/accounts/login/')
        browser.find_element_by_name('login').send_keys(user.email)
        browser.find_element_by_name('password').send_keys(password)
        browser.find_element_by_css_selector('button[type="submit"]').click()
        browser.implicitly_wait(2)

        assert f'Successfully signed in as {user.username}' in browser.page_source

test_site_loads проходит, test_valid_login терпит неудачу, и если я приведу пример browser.current_url, он по-прежнему указывает на / account / login /.Если я посмотрю на исходный код страницы, используя browser.page_source, то увижу «Неверный указанный вами адрес электронной почты и / или пароль».в списке ошибок формы входа в систему.

Я понятия не имею, почему учетные данные входа в систему здесь терпят неудачу, и я не могу думать ни о чем другом, чтобы посмотреть.

Вот что я вижу в browser.page_source (захватывается с помощью print непосредственно перед оператором assert), о котором я упоминал выше:

<form action="/accounts/login/" class="login auth-form" method="post"> 
<input type="hidden" name="csrfmiddlewaretoken" value="xLRQ8nZlfocyyQDlJxgLL0PUvsYLLNYNHEZ5awn8cLseQoR2XNQm4TiKOgMvcaS9"> 
<div class="alert alert-block alert-danger">
    <ul>
        <li>The e-mail address and/or password you specified are not correct.</li>
    </ul>
</div> 
<div id="div_id_login" class="form-group">
    <div class="">
        <input type="email" name="login" value="ricardosoto@gmail.com" placeholder="E-mail address" autofocus="autofocus" class="textinput textInput form-control" required="" id="id_login">
    </div>
</div> 
<div id="div_id_password" class="form-group"> 
    <div class=""> 
        <input type="password" name="password" placeholder="Password" class="textinput textInput form-control" required="" id="id_password">
    </div>
</div> 
    <button class="btn btn-lg btn-primary btn-block" type="submit">Sign In</button> 
</form>

Я также включил соответствующие приборы для испытаний:

import environ
import pytest
import socket

from django.conf import settings

from selenium.webdriver import Remote
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

from pytest_django.live_server_helper import LiveServer

from users.tests.factories import UserFactory


env = environ.Env()


@pytest.fixture
def browser() -> Remote:
    driver = Remote(
        command_executor=env('SELENIUM_HOST', default='http://selenium:4444/wd/hub'),
        desired_capabilities=DesiredCapabilities.FIREFOX
    )
    yield driver
    driver.quit()


@pytest.fixture
def test_server() -> LiveServer:
    addr = socket.gethostbyname(socket.gethostname())
    server = LiveServer(addr)
    yield server
    server.stop()


@pytest.fixture
def user() -> settings.AUTH_USER_MODEL:
    return UserFactory()

Так же, как проверка работоспособности, я попытался добавить пару дополнительных print операторов, чтобы проверить все непосредственно перед assert:

    print('User email: ' + user.email)
    print('User is active? ' + str(user.is_active))
    print('Password valid? ' + str(user.check_password(password)))
    print('URL: ' +browser.current_url)

Дает мне:

User email: rparsons@yahoo.com
User is active? True
Password valid? True
URL: http://172.19.0.6:44025/accounts/login/

Я также попытался добавить дополнительный тест, который обходит Selnium, чтобы попытаться изолировать проблему немного больше:

class TestAccountLoginView:
    def test_valid(self, client, user: settings.AUTH_USER_MODEL, request_factory: RequestFactory):
        password = 'password'
        user.set_password(password)
        user.save()

        response = client.post('/accounts/login/', {'login': user.email, 'password': password})

        assert response.status_code == 302

Это работает, как ожидалось, и регистрирует меня просто отлично.

Обновление,

Похоже, это на самом деле может иметь какое-то отношение к LiveServer pytest-django.Игнорируя приспособление live_server и используя StaticLiveServerTestCase Джанго, я могу войти в систему просто отлично:

class TestDashboard(StaticLiveServerTestCase):

    @classmethod
    def setUpClass(cls):
        cls.host = socket.gethostbyname(socket.gethostname())
        super().setUpClass()
        cls.selenium = Remote(
            command_executor='http://selenium:4444/wd/hub',
            desired_capabilities=DesiredCapabilities.FIREFOX
        )
        cls.selenium.implicitly_wait(10)

    @classmethod
    def tearDownClass(cls):
        cls.selenium.quit()
        super().tearDownClass()

    def test_login(self):
        get_user_model().objects.create_user(username='testuser', email='test@example.com', password='password')

        self.selenium.get('%s%s' % (self.live_server_url, '/accounts/login/'))
        username_input = self.selenium.find_element_by_name("login")
        username_input.send_keys('test@example.com')
        password_input = self.selenium.find_element_by_name("password")
        password_input.send_keys('password')
        self.selenium.find_element_by_xpath('//button[@type="submit"]').click()

        assert 'Successful' in self.selenium.page_source

Не совсем уверен, почему LiveServer pytest-django делает это, но, по крайней мере, у меня где-то естьсмотреть сейчас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...