Warm tip: This article is reproduced from stackoverflow.com, please click
django python selenium django-testing

Cannot login user for testing with selenium in Django?

发布于 2020-03-27 10:23:14

I've got the following test:

class FirefoxTestCases(StaticLiveServerTestCase):
    def setUp(self):
        user = User.objects.create(
            first_name="user",
            last_name="one",
            username="userone",
            is_active=True,
        )
        user.set_password("test")
        user.save()
        self.client = webdriver.Firefox()

    def tearDown(self):
        self.client.quit()

    def test_log_in_displays_firefox(self):
        # Opening the link we want to test
        self.client.get(self.live_server_url)
        assert "log in" in self.client.page_source
        self.client.find_element_by_id("id_username").send_keys("userone")
        self.client.find_element_by_id("id_password").send_keys("test")
        self.client.find_element_by_id("log_in").click()
        time.sleep(2)
        # Check the returned result
        assert "appone" in self.client.page_source

The app takes you to a login page right off the bat and talks to a log_in view

def log_in(request):
    if request.user.is_authenticated:
        return redirect("launcher")
    if request.method == "POST":
        form = LoginForm(request.POST)
        if form.is_valid():
            user = authenticate(
                request,
                username=request.POST.get("username"),
                password=request.POST.get("password"),
            )
            if user is not None:
                login(request, user)
                # 500 error occurs here
                return redirect("launcher")
        return render(request, "launcher/login.html", {"form": form})
    else:
        form = LoginForm()
        return render(request, "launcher/login.html", {"form": form})

The form submits without issue but it gives a 500 error in the logs. It redirects to the login page again (expected).

I have another test where I login the same user programmatically that does work:

class TestViews(TestCase):
    def setUp(self):
        user = User.objects.create(
            first_name="user",
            last_name="two",
            username="usertwo",
            is_active=True,
        )
        user.set_password("test")
        user.save()            

def test_logged_in_one_app_returns_200_and_launcher(self):
    """
    A user with one app sees the launcher.html page
    """
    user = User.objects.get(username="usertwo")
    user.set_password("test")
    user.save()
    test_client = Client()
    test_client.login(username="usertwo", password="test")
    response = test_client.get("/", follow=True)
    self.assertEqual(response.status_code, 200)
    self.assertTemplateUsed(response, "launcher/launcher.html")

That test passes and works as intended.

I can't figure out why I get the 500 in the test with selenium given that the user does exist and I set the password... I'm not sure what is going wrong.

If I fire it up locally - I can login as a user without issue and it all works. But it's only when I'm testing it that the user login fails.

Questioner
Hanny
Viewed
101
Hanny 2019-07-04 03:29

Apparently having a redirect here:

        if user is not None:
            login(request, user)
            # 500 error occurs here
            return redirect("launcher")

Is the issue that ends up causing problems (although I'm not sure why).

I replaced that section with this:

        if user is not None:
            login(request, user)
            if not request.user.groups.all():
                return render(request, "launcher/no_apps.html")
            return render(
                request,
                "launcher/launcher.html",
                {
                    "apps": App.objects.filter(
                        groups__in=request.user.groups.all()
                    ).distinct()
                },
            )

Which worked.

I'm not sure why the redirect did not - but rendering it out here works in the test environment as well as live.