[Python] Using PyTest and Playwright, run one method before loading all the test files

Discussão em 'Python' iniciado por Stack, Agosto 29, 2025.

  1. Stack

    Stack Membro Participativo

    This question seems to be asked a lot, but I'm not finding any answers that work, or at least that work for what I'm looking for.

    The premise is simple: I have a website I need to automate testing on (using Playwright with PyTest). I can use browser.new_context(storage_state=auth_file), which puts me in a logged in state, and the testing runs as expected.

    But for security reasons, that session times out after a few days, making the auth_file invalid. Or when someone pulls in the repo, there is no auth_file and when they try to tun pytest it's 100% errors because they're stuck on the login screen.

    I added a fixture that all the other fixtures depend on that looks to see if the auth_file exists, or if it's modified date is too far back, and if so, run the authentication_login() function (creates a browser window, not-headless, so that I can go through the login process). But all that did was make every test open to the same login page.

    So how do I create something that runs even before pytest looks for tests to run?

    Here is what I have so far:

    auth_file: Path = Path(".auth/storage_state.json")

    @pytest.fixture(scope="session", autouse=True)
    def authentication():
    TIME_OUT: int = 60 * 60

    if not auth_file.is_file() or (time.time() - auth_file.stat().st_mtime) > TIME_OUT:
    authentication_login()

    yield

    @pytest.fixture
    def playwright(authentication):
    with sync_playwright() as p:
    yield p


    @pytest.fixture
    def browser_context(playwright):
    browser: Browser = playwright.chromium.launch(**options)
    context: BrowserContext = browser.new_context(
    storage_state=auth_file
    )
    yield context
    context.close()
    browser.close()


    @pytest.fixture
    def page(browser_context, request):
    page: Page = browser_context.new_page()
    page.goto("http://localhost/")
    wait_for_loaders_to_complete(page)
    yield page
    page.close()

    def authentication_login():
    with sync_playwright() as playwright:
    browser = playwright.chromium.launch(headless=False, slow_mo=500)

    context = browser.new_context()
    page = context.new_page()
    page.goto("http://localhost/")
    page.pause()

    login_button: Locator = page.get_by_role("button", name="Login")
    if login_button.is_visible():
    login_button.click()
    ...
    # Save authentication state
    context.storage_state(path=".auth/storage_state.json")
    print("New authentication saved.")
    context.close()
    browser.close()



    Part of the problem is that the login routine includes using a OTP, so it really needs to be a human going through the login process ONCE, and after that is done, then all the other tests can launch their own windows (headless or not). Eventually, it will be a dummy account that doesn't need the authenticator, but I would still have the issue of 10+ sessions all trying to login. After the first succeeds, all new sessions will have the valid auth_file.

    Continue reading...

Compartilhe esta Página