Can't capture browser error logs in playright test w/ python

57 Views Asked by At

I am writing functional tests in python w/ playright + pytest. I'm writing a test to identify any errors in the browser log.

I can't seem to grab the contents of the log though. It seems like the code is not loading in the correct sequential order for some reason. I know there are errors, but where I'm trying to capture them, it returns None.

Below is my code:

@pytest.mark.django_db(transaction=True)
def test_can_load_pages_without_error(login_to_myscore):
    # login
    page = login_to_myscore
    # Retrieve testing objects
    testing_objects = get_testing_objects('all')
    # load up the page for each object
    for object in tqdm(testing_objects):
        url = page.goto(f'http://localhost:{local_port}/production/{str(object.slug)}')
        # check for errors
        can_load_page_without_errors(url, page)

This calls the below function:

def can_load_page_without_errors(url, page):

    print("THE URL: ", url)

    # page.on("console", lambda msg: print(f"A1: {msg.text}") if msg.type == "error" else None)
    # page.on("console", lambda msg: print(f"A2:{msg.text}"))

    page.on("pageerror", lambda exc: print(f"1: {exc}"))

    page.on("pageerror", lambda err: print(f"2: {err.message}"))

    # check for any uncaught errors logged to browser console
    uncaught_errors = []
    # uncaught_error = page.on("pageerror", lambda error: error)

    # Define a function to handle the pageerror event
    def handle_pageerror(error):
        print("3", error)
        print("4", type(error))
        error = str(error)
        print("5", type(error))
        return error

    # Attach the function to the pageerror event
    uncaught_error = page.on("pageerror", handle_pageerror)
    uncaught_errors.append(uncaught_error)
    print("6", uncaught_error)
    print("7", uncaught_errors)
    # assert len(uncaught_errors) == 0, f"The following uncaught JavaScript errors were reported for {url}:\n{uncaught_error}"

Below is the order it prints:

URL:  http://localhost:8080/production/1538
6 None
7 [None]
1: overflows is not defined
2: overflows is not defined
3 overflows is not defined
4 <class 'playwright._impl._errors.Error'>
5 <class 'str'>

You'll notice (6) and (7) print first for some reason...and the results are None. But the error prints out in (1), (2), (3)...

Why is it doing this?

I thought Playwright was supposed to be a lot better at handling await stuff (which was a big reason why I chose this over Selenium). I've tried a bunch of ways to delay the page load, but that hasn't seemed to make a difference, so maybe it isn't that...?

I just want to be able to grab the results of the page.on("console") and page.on("pageerror"), but I can't seem to do that because of the way the function is rendering / loading (out of order).

Any thoughts on why / how I can do this?

Thank You!

1

There are 1 best solutions below

0
Matt S On

For anyone else who experiences this, the solution was to place the event handler (page.on()) before loading the webpage!

    # build the URL of our page
    url = f'http://localhost:{local_port}/{app}/{str(object.slug)}'
    print(" PAGE URL: ", url)

    # append any uncaught javascript errors in browser error logs to list
    uncaught_errors = []
    page.on("pageerror", lambda exc: uncaught_errors.append(exc))

    # append any javascript errors in browser error logs to list
    error_logs = []
    page.on("console", lambda msg: error_logs.append(msg.text) if msg.type == "error" else None)

    # go to page once there are no more than 2 network connections for at least 500 milliseconds
    page.goto(url, wait_until="networkidle")

    # assert that 'Page Not Found' is not in title tag of DOM
    title = page.title()
    assert 'Page Not Found' not in title, '\n\n 404 error!'

    # assert that no uncaught javascript errors are in browser error logs
    assert len(uncaught_errors) == 0, f"The following uncaught JavaScript errors were reported for {url}:\n{uncaught_errors}"

    # assert that no javascript errors are in browser error logs
    assert len(error_logs) == 0, f"The following JavaScript errors were reported for {url}:\n{error_logs}"