diff --git a/README.md b/README.md index e4c1624da..a0c304952 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,24 @@ def test_playwright_is_visible_on_google(page): For more information on pytest-playwright, see [GitHub](https://github.com/microsoft/playwright-pytest#readme). +#### REPL support without context managers + +For scripting purposes, it is also possible to start and stop Playwright manually without relying on the indentation of the REPL. + +```py +from playwright import sync_playwright + +playwright = sync_playwright().start() +for browser_type in [playwright.chromium, playwright.firefox, playwright.webkit]: + browser = browser_type.launch() + page = browser.newPage() + page.goto("http://whatsmyuseragent.org/") + page.screenshot(path=f"example-{browser_type.name}.png") + browser.close() + +playwright.stop() +``` + ## More examples #### Mobile and geolocation diff --git a/playwright/async_api.py b/playwright/async_api.py index 4bb1831e7..e6ae2d60a 100644 --- a/playwright/async_api.py +++ b/playwright/async_api.py @@ -5942,5 +5942,8 @@ def selectors(self) -> "Selectors": def devices(self) -> typing.Dict[str, DeviceDescriptor]: return mapping.from_maybe_impl(self._impl_obj.devices) + def stop(self) -> NoneType: + return mapping.from_maybe_impl(self._impl_obj.stop()) + mapping.register(PlaywrightImpl, Playwright) diff --git a/playwright/main.py b/playwright/main.py index 049535ec6..5a7547e11 100644 --- a/playwright/main.py +++ b/playwright/main.py @@ -93,9 +93,14 @@ def callback_wrapper(playwright_impl: Playwright) -> None: self._connection.call_on_object_with_known_name("Playwright", callback_wrapper) set_dispatcher_fiber(greenlet(lambda: self._connection.run_sync())) dispatcher_fiber().switch() - return self._playwright + playwright = self._playwright + playwright.stop = self.__exit__ # type: ignore + return playwright - def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None: + def start(self) -> SyncPlaywright: + return self.__enter__() + + def __exit__(self, *args: Any) -> None: self._connection.stop_sync() @@ -106,11 +111,16 @@ def __init__(self) -> None: async def __aenter__(self) -> AsyncPlaywright: self._connection = await run_driver_async() self._connection.run_async() - return AsyncPlaywright( + playwright = AsyncPlaywright( await self._connection.wait_for_object_with_known_name("Playwright") ) + playwright.stop = self.__aexit__ # type: ignore + return playwright + + async def start(self) -> AsyncPlaywright: + return await self.__aenter__() - async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None: + async def __aexit__(self, *args: Any) -> None: self._connection.stop_async() diff --git a/playwright/playwright.py b/playwright/playwright.py index f2c561390..5aca9398f 100644 --- a/playwright/playwright.py +++ b/playwright/playwright.py @@ -39,3 +39,6 @@ def __init__( device["name"]: device["descriptor"] for device in initializer["deviceDescriptors"] } + + def stop(self) -> None: + pass diff --git a/playwright/sync_api.py b/playwright/sync_api.py index f6473cefe..e8ec9f16b 100644 --- a/playwright/sync_api.py +++ b/playwright/sync_api.py @@ -6182,5 +6182,8 @@ def selectors(self) -> "Selectors": def devices(self) -> typing.Dict[str, DeviceDescriptor]: return mapping.from_maybe_impl(self._impl_obj.devices) + def stop(self) -> NoneType: + return mapping.from_maybe_impl(self._impl_obj.stop()) + mapping.register(PlaywrightImpl, Playwright)