Search code examples
pythonpython-3.xdjangoplaywright

How to save django db data in the middle of a playwright test?


I'm having trouble figuring out how to call the "sync" create_user().

Error message:

django.core.exceptions.SynchronousOnlyOperation: 
You cannot call this from an async context - use a thread or sync_to_async.

However, when I use sync_to_async, it cannot be awaited because this is not an async function...

from functools import wraps

from django.test import TestCase
from playwright.sync_api import sync_playwright


def playwright_test(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        with sync_playwright() as self.p:
            self.browser = self.p.chromium.launch()
            self.page = self.browser.new_page()
            try:
                result = func(self, *args, **kwargs)
            finally:
                self.browser.close()
            return result

    return wrapper


class TC(TestCase):
    @playwright_test
    def test_login(self):
        self.page.goto(self.host)
        self.page.fill('input[type="email"]', '[email protected]')
        self.page.fill('input[type="password"]', 'TestLogin')
        self.page.click('text="Login"')
        # expect "Incorrect Credentials" message (no user created yet)
        assert "Incorrect Credentials" in self.page.content()

        User = get_user_model()
        User.objects.create_user('[email protected]', password='TestLogin')

        # Login again, this time successfully
        self.page.fill('input[type="email"]', '[email protected]')
        self.page.fill('input[type="password"]', 'TestLogin')
        self.page.click('text="Login"')
        assert "Login successful. Welcome back!" in self.page.content()

If you have a suggestion, please let me know, my hair starts to fall out. 🙏


Solution

  • As @CoffeeBasedLifeform generously wrote in https://stackoverflow.com/a/78651148/1031191 , for django the solution is https://github.com/microsoft/playwright-pytest/issues/29#issuecomment-731515676

    Copying the link contents here:

    For running Django tests with playwright you need to set environment variable DJANGO_ALLOW_ASYNC_UNSAFE = "true" django docs on this
    This can be done by creating a conftest.py in the tests directory and setting the environment variable using

    # conftest.py import os 
    os.environ.setdefault("DJANGO_ALLOW_ASYNC_UNSAFE","true")