Selenium无法登录到Django LiveServerTestCase

Selenium无法登录到Django LiveServerTestCase,django,selenium,testing,pytest,Django,Selenium,Testing,Pytest,我正努力让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_help

我正努力让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\u site\u load
通过,
test\u valid\u login
失败,如果我使用示例
browser.current\u url
它仍然指向/accounts/login/。如果我使用
浏览器查看页面源。page\u source
,我可以在登录表单的错误列表中看到“您指定的电子邮件地址和/或密码不正确”

我不知道为什么登录凭据在这里失败,我想不出还有什么可以看的

以下是我在
浏览器中看到的内容。我在上面提到的
断言
语句之前通过
打印
捕获的页面源代码:

<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>
作为一个合理性检查,我尝试添加两个额外的
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
这是预期的工作和日志我刚刚好

更新,

看起来这实际上可能与pytest django的LiveServer有关。忽略
live_服务器
fixture,使用Django的
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

我不太清楚为什么pytest django的LiveServer会这样做,但至少我现在有地方可以看看。

1。你能提供更多关于“它失败”的信息吗?2.在browser.get(blabla)之后,我会使用time.sleep(3)让页面加载(以防万一),如果这样做没有帮助,请尝试将find_element_by_name更改为xpath,但不确定还需要添加什么。
test\u valid\u login
测试在断言中失败。如果我输出断言所针对的
browser.page\u source
,它只是登录页面,并且在登录表单中有一个错误:“您指定的电子邮件地址和/或密码不正确。”。“作为{}成功登录”。格式(user.username)似乎没有什么区别。仍然看到登录失败。我将把我看到的表格添加到问题中。也许有用?@Micromegas对不起,我从来没有让它正常工作过,而且由于时间限制,我从来没有机会深入研究。如果我找到了解决方案,我会在这里更新。1。你能提供更多关于“它失败”的信息吗?2.在browser.get(blabla)之后,我会使用time.sleep(3)让页面加载(以防万一),如果这样做没有帮助,请尝试将find_element_by_name更改为xpath,但不确定还需要添加什么。
test\u valid\u login
测试在断言中失败。如果我输出断言所针对的
browser.page\u source
,它只是登录页面,并且在登录表单中有一个错误:“您指定的电子邮件地址和/或密码不正确。”。“作为{}成功登录”。格式(user.username)似乎没有什么区别。仍然看到登录失败。我将把我看到的表格添加到问题中。也许有用?@Micromegas对不起,我从来没有让它正常工作过,而且由于时间限制,我从来没有机会深入研究。如果我找到了解决方案,我会在这里更新。
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