Skip to content
Go back

Test Automation - How to Bypass Re-Login With Playwright Python And Pytest

Published:

Introduction

In the realm of web application testing, one of the recurring challenges lies in the need to authenticate or log in for every test iteration. This repetitive process consumes valuable testing time. With each test opening a new browser page, the overhead of authenticating can quickly accumulate, slowing down the testing pipeline.

Fortunately, modern browser automation tools like Playwright offer capabilities that can help alleviate this pain point. By leveraging Playwright’s session storage functionality, it becomes possible to persist authenticated sessions across multiple tests, eliminating the need for redundant login steps.

The solution presented in this article is exemplified in the Pytest fixtures incorporated into my Playwright Python example project, developed in collaboration with Elias Shourosh. These fixtures not only showcase the implementation details but also serve as a practical reference for integrating persistent authentication into your testing workflows, empowering you to maximize your testing productivity.

Implementing the Solution

The solution code can be found here.

@pytest.fixture(scope="function")
def browser_context_args(
    browser_context_args: Dict, base_url: str, request: SubRequest
):
    """This fixture allows setting browser context arguments for Playwright.

    Args:
        browser_context_args (dict): Base browser context arguments.
        request (SubRequest): Pytest request object to get the 'browser_context_args' fixture value.
        base_url (str): The base URL for the application under test.

    Returns:
        dict: Updated browser context arguments.

    See Also:
        https://playwright.dev/python/docs/api/class-browser#browser-new-context
    """
    context_args = {
        **browser_context_args,
        "no_viewport": True,
        "user_agent": Constants.AUTOMATION_USER_AGENT,
    }

    if hasattr(request, "param"):
        context_args["storage_state"] = {
            "cookies": [
                {
                    "name": "session-username",
                    "value": request.param,
                    "url": base_url,
                }
            ]
        }
    return context_args

This Pytest fixture is designed to set up the arguments for a Playwright browser context. Let’s break down the code:

@pytest.fixture(scope=“function”):

Parameters:

Return Value:

Key Actions:

  1. Maximizing Browser Window: explained in a previous article
  2. Conditional Cookie Handling:

Key takeaways:

@pytest.fixture(scope="function", autouse=True)
def goto(page: Page, request: SubRequest):
    """Fixture to navigate to the base URL based on the user.

    If the 'storage_state' is set in 'browser_context_args', it navigates to the inventory page,
    otherwise, it navigates to the login page.

    Args:
        page (Page): Playwright page object.
        request (SubRequest): Pytest request object to get the 'browser_context_args' fixture value.
            If 'browser_context_args' is set to a user parameter (e.g., 'standard_user'),
            the navigation is determined based on the user.

    Example:
        @pytest.mark.parametrize('browser_context_args', ["standard_user"], indirect=True)
    """
    if request.getfixturevalue("browser_context_args").get("storage_state"):
        page.goto("/inventory.html")
    else:
        page.goto("")

This fixture automates navigation to a specific URL within a test function, adapting based on user context.

@pytest.fixture(scope=“function”, autouse=True):

Parameters:

Navigation Logic:

  1. Conditional URL Selection: to check if the fixture contains a key. indicates a logged-in user.
  2. Navigation Based on User Context:

Key Takeaways:

Test Usage

The test usage can be found here.

@pytest.mark.parametrize("browser_context_args", ["standard_user"], indirect=True)
def test_inventory_page(self, browser_context_args, page: Page):
    assert page.inner_text("//span[@class='title']") == "Products"

Test Decorator:

Test Function Parameters:

In Conclusion

The provided code showcases the implementation of Pytest fixtures in Python Playwright to overcome the challenge of frequent re-login requirements during browser testing. By leveraging Playwright’s session storage capability within the Pytest fixtures, automation engineers can maintain persistent sessions across multiple tests, significantly improving testing efficiency and productivity. The fixtures intelligently manage browser context arguments, ensuring that each test iteration opens within an existing session with predefined cookies, eliminating the need for repetitive login procedures. This approach streamlines the testing workflow and enhances the overall reliability of browser testing. Additionally, a small test usage demonstrates how the fixtures seamlessly integrate into testing scenarios, further highlighting their practicality and effectiveness in real-world testing environments.

Happy testing!


Suggest Changes

Ready to build your quality roadmap? Start Here


Previous Post
Test Automation - Maximizing Browser Window With Playwright Python And Pytest
Next Post
Test Automation - How To Perform Automated Accessibility Checks Using Playwright Python And Axe