How to make assertion of dialog.message in playwright?

561 views Asked by At

In one of my tests I need to assert message in browser dialog. I created dialog handler in test

page.on('dialog', BasePage.dialog_handle)

page is default playwright fixture.

The handler itself is

def dialog_handle(dialog):
    message = dialog.message
    dialog.dismiss()

Here is full example of the test with dialog on the page

from playwright.sync_api import Page


def dialog_handle(dialog):
    message = dialog.message
    dialog.dismiss()


def test_dialog(page):
    page.goto('https://dialog.antonzimaiev.repl.co')
    page.on('dialog', dialog_handle)
    page.get_by_role("button", name="Диалог Alert").click()

How can I retrieve dialog.message to assert it using pytest?

1

There are 1 answers

2
ggorlen On BEST ANSWER

This can be solved with some scoping readjustments:

from playwright.sync_api import sync_playwright  # 1.37.0


def test_dialog(page):
    dialog_message = None

    def handle_dialog(dialog):
        nonlocal dialog_message

        # assert here
        print(dialog.message) # => Hello from Open Solutions 

        # or save the message in the enclosing scope...
        dialog_message = dialog.message
        dialog.dismiss()

    page.goto("https://dialog.antonzimaiev.repl.co")
    page.once("dialog", handle_dialog)
    page.get_by_role("button", name="Диалог Alert").click()

    # ... and assert here
    print(dialog_message) # => Hello from Open Solutions 


if __name__ == "__main__":
    with sync_playwright() as p:
        browser = p.chromium.launch(headless=True)
        page = browser.new_page()
        test_dialog(page)

There's nothing special about pytest per se here--you can drop the test_dialog function body right into a pytest test case and use assertions from that, or any other testing library you like.

Race conditions aren't an issue here since the dialog blocks the script after the .click() operation until it's dismissed.


This pattern can be factored to be reusable across tests or in a POM, if that's a concern. For example:

def accept_dialog(page, trigger_dialog):
    dialog_message = None

    def handle_dialog(dialog):
        nonlocal dialog_message
        dialog_message = dialog.message
        dialog.dismiss()

    page.once("dialog", handle_dialog)
    trigger_dialog()
    return dialog_message


def test_dialog(page):
    page.goto("https://dialog.antonzimaiev.repl.co")
    dialog_message = accept_dialog(
        page,
        lambda: page.get_by_role("button", name="Диалог Alert").click()
    )
    print(dialog_message) # => Hello from Open Solutions