Goal: I am trying to create a function decorator which passes a Playwright Page
(playwright.sync_api._generated.Page)
object to the wrapped function.
Issue: For most function calls, I would be able to return the value returned by the function call. However, since Playwright necessitates the browser.close()
call, I can't simply return the Page
object. I am not sure whether the problem is in (1) the function decorator which I have defined, or (2) my usage of the function decorator.
I tried to model my decorator after pytest
fixtures. Using pytest
, I would do something like this:
@pytest.fixture(scope="module")
def playwright_page():
with sync_playwright() as play:
browser = play.chromium.launch()
page = browser.new_page()
yield page
browser.close()
and then
def open_google(playwright_page):
playwright_page.goto("https://google.com")
Function Decotator:
>>> from playwright.sync_api import sync_playwright
>>> def playwright_page(func):
def wrapper(*args, **kwargs):
with sync_playwright() as play:
browser = play.chromium.launch()
page = browser.new_page()
yield page
browser.close()
return wrapper
Attempt 1:
>>> @playwright_page
def open_google():
page.goto("https://google.com")
>>> open_google()
<generator object playwright_page.<locals>.wrapper at 0x0000015C5F6CBC10>
Attempt 2:
>>> @playwright_page
def open_google():
page = next(page)
page.goto("https://google.com")
>>> open_google()
<generator object playwright_page.<locals>.wrapper at 0x0000015C5FDB7F90>
Instead of trying to yield the Page
object, such as for pytest
fixtures, I should have been calling func
and passing the Page
object.
>>> from playwright.sync_api import sync_playwright
>>> def playwright_page(func):
def wrapper():
with sync_playwright() as play:
browser = play.chromium.launch()
page = browser.new_page()
results = func(page)
browser.close()
return results
return wrapper
>>> @playwright_page
def open_google(page):
page.goto("https://google.com")