Skip to content

Commit d25d6bb

Browse files
committed
auto_closing_level library parameter
1 parent 98791f7 commit d25d6bb

File tree

4 files changed

+61
-9
lines changed

4 files changed

+61
-9
lines changed

Browser/browser.py

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
)
2121
from .playwright import Playwright
2222
from .utils import logger
23+
from .utils.data_types import AutoClosingLevel
2324
from .version import VERSION
2425

2526

@@ -141,15 +142,30 @@ class Browser(DynamicCore):
141142
Builtin Evaluating expressions]
142143
for more info on the syntax.
143144
145+
= Automatic page and context closing =
146+
147+
Library will close pages and contexts that are created during test execution.
148+
Pages and contexts created before test in Suite Setup or Suite Teardown will be closed after that suite.
149+
This will remove the burden of closing these resources in teardowns.
150+
151+
Browsers will not be automatically closed. A browser is expensive to create and should be reused.
152+
153+
Automatic closing can be configured or switched off with the ``auto_closing_level`` library parameter.
144154
"""
145155

146156
ROBOT_LIBRARY_VERSION = VERSION
147157
ROBOT_LISTENER_API_VERSION = 2
148158
ROBOT_LIBRARY_LISTENER: "Browser"
149159
ROBOT_LIBRARY_SCOPE = "GLOBAL"
150160
SUPPORTED_BROWSERS = ["chromium", "firefox", "webkit"]
151-
152-
def __init__(self, timeout="10s", enable_playwright_debug: bool = False):
161+
_auto_closing_level: AutoClosingLevel
162+
163+
def __init__(
164+
self,
165+
timeout="10s",
166+
enable_playwright_debug: bool = False,
167+
auto_closing_level: AutoClosingLevel = AutoClosingLevel.TEST,
168+
):
153169
"""Browser library can be taken into use with optional arguments:
154170
155171
- ``timeout``:
@@ -158,6 +174,10 @@ def __init__(self, timeout="10s", enable_playwright_debug: bool = False):
158174
- ``enable_playwright_debug``:
159175
Enable low level debug information from the playwright tool. Mainly
160176
Useful for the library developers and for debugging purposes.
177+
- ``auto_closing_level``:
178+
Configure context and page automatic closing. Default is after each test.
179+
Other options are SUITE for closing after each suite and MANUAL
180+
for no automatic closing.
161181
"""
162182
self.ROBOT_LIBRARY_LISTENER = self
163183
self._execution_stack: List[object] = []
@@ -180,6 +200,7 @@ def __init__(self, timeout="10s", enable_playwright_debug: bool = False):
180200
WebAppState(self),
181201
]
182202
self.playwright = Playwright(timeout, enable_playwright_debug)
203+
self._auto_closing_level = auto_closing_level
183204
DynamicCore.__init__(self, libraries)
184205

185206
@property
@@ -190,21 +211,25 @@ def _close(self):
190211
self.playwright.close()
191212

192213
def _start_suite(self, name, attrs):
193-
self._execution_stack.append(self.getters.get_browser_catalog())
214+
if self._auto_closing_level != AutoClosingLevel.MANUAL:
215+
self._execution_stack.append(self.getters.get_browser_catalog())
194216

195217
def _start_test(self, name, attrs):
196-
self._execution_stack.append(self.getters.get_browser_catalog())
218+
if self._auto_closing_level == AutoClosingLevel.TEST:
219+
self._execution_stack.append(self.getters.get_browser_catalog())
197220

198221
def _end_test(self, name, attrs):
199222
if len(self.promises._unresolved_promises) > 0:
200223
logger.warn(f"Waiting unresolved promises at the end of test '{name}'")
201224
self.wait_for_all_promises()
202-
catalog_before_test = self._execution_stack.pop()
203-
self._prune_execution_stack(catalog_before_test)
225+
if self._auto_closing_level == AutoClosingLevel.TEST:
226+
catalog_before_test = self._execution_stack.pop()
227+
self._prune_execution_stack(catalog_before_test)
204228

205229
def _end_suite(self, name, attrs):
206-
catalog_before_suite = self._execution_stack.pop()
207-
self._prune_execution_stack(catalog_before_suite)
230+
if self._auto_closing_level != AutoClosingLevel.MANUAL:
231+
catalog_before_suite = self._execution_stack.pop()
232+
self._prune_execution_stack(catalog_before_suite)
208233

209234
def _prune_execution_stack(self, catalog_before):
210235
# WIP CODE BEGINS
@@ -233,6 +258,7 @@ def _prune_execution_stack(self, catalog_before):
233258
self.playwright_state.switch_context(ctx_id)
234259
self.playwright_state.switch_page(page_id)
235260
self.playwright_state.close_page()
261+
# try to set active page and context back to right place.
236262
for browser in catalog_after:
237263
if browser["activeBrowser"]:
238264
activeContext = browser.get("activeContext", None)

Browser/utils/data_types.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ class SupportedBrowsers(Enum):
4242
ViewportDimensions = TypedDict("ViewportDimensions", {"width": int, "height": int})
4343

4444

45+
class AutoClosingLevel(Enum):
46+
SUITE = "SUITE"
47+
TEST = "TEST"
48+
MANUAL = "MANUAL"
49+
50+
4551
class ElementState(Enum):
4652
attached = auto()
4753
detached = auto()

atest/test/01_Browser_Management/auto_closing.robot renamed to atest/test/01_Browser_Management/Auto_Closing/auto_closing.robot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
*** Settings ***
22
Library Browser
3-
Resource imports.resource
3+
Resource ../imports.resource
44
Suite Setup New Page ${ERROR_URL}
55

66
*** Test Cases ***
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
*** Settings ***
2+
Library Browser auto_closing_level=SUITE
3+
Resource ../imports.resource
4+
Suite Setup New Page ${ERROR_URL}
5+
6+
*** Test Cases ***
7+
Resource leaker
8+
New context
9+
New Page ${WELCOME_URL}
10+
11+
New context is not closed after test
12+
Get title == Welcome Page
13+
14+
Page leaker
15+
Go to ${WELCOME_URL}
16+
New Page ${FORM_URL}
17+
Get title == prefilled_email_form.html
18+
19+
New page is not closed after test
20+
Get title == prefilled_email_form.html

0 commit comments

Comments
 (0)