Principle:MarketSquare Robotframework browser Test Cleanup and Failure Handling
| Property | Value |
|---|---|
| Principle Name | Test Cleanup and Failure Handling |
| Domains | Test_Automation, Resource_Management |
| Workflow | Browser_Test_Authoring |
| Repository | MarketSquare/robotframework-browser |
| Type | Principle |
Overview
Automatic resource cleanup and configurable failure recovery mechanisms ensure reliable test execution by managing browser lifecycle and capturing diagnostic information when failures occur.
Description
The Test Cleanup and Failure Handling principle addresses two critical concerns in browser test automation:
1. Resource Cleanup (Auto-Closing)
Browser processes, contexts, and pages consume system resources (memory, file handles, network connections). If not properly closed, they accumulate across test runs, causing resource exhaustion, flaky tests, and CI pipeline failures. The Browser library provides an auto-closing mechanism that automatically closes browser resources at configurable lifecycle boundaries:
- TEST level (default): All contexts and pages created during a test are automatically closed when the test ends. This provides maximum isolation between tests.
- SUITE level: Resources persist across tests within a suite and are closed when the suite finishes. Useful when tests share a browser session for performance.
- MANUAL level: No automatic closing. The test author must explicitly close resources using
Close Browser,Close Context, orClose Page.
The auto-closing level is configured at library import time via the auto_closing_level parameter.
Explicit closing is also available through the Close Browser keyword, which can close the current browser, a specific browser by ID, or all browsers. Closing a browser closes all of its contexts and pages.
2. Run-On-Failure (Failure Handling)
When a Browser keyword fails, it is often critical to capture the state of the page at the moment of failure for debugging. The run-on-failure mechanism automatically executes a specified keyword whenever any Browser keyword raises an error. The default behavior is to take a screenshot, saving it with an auto-incrementing index.
Key features of the run-on-failure mechanism:
- Configurable at import: The default failure keyword is set via the
run_on_failureparameter at library import. - Scoped registration: The failure keyword can be changed at Global, Suite, or Test scope using the
Register Keyword To Run On Failurekeyword. Scoped changes are automatically reverted when the scope ends. - Disabling: Setting the failure keyword to
NONEdisables the mechanism entirely. - Restoring previous: The registration keyword returns the previously registered keyword, allowing it to be restored later.
- Guard against recursion: The library tracks whether it is currently executing a failure handler to prevent infinite loops if the failure handler itself fails.
Usage
Use this principle when:
- You need reliable test isolation and want browser resources cleaned up automatically between tests.
- You need diagnostic information (screenshots, traces) captured automatically when tests fail.
- You want to switch between different failure handling strategies at different test scopes (e.g., full-page screenshots at suite level, element-specific screenshots at test level).
- You need to temporarily disable failure handling for specific test sections (e.g., testing error conditions where failures are expected).
Theoretical Basis
AUTO_CLOSING:
# Configured at library import: auto_closing_level = TEST | SUITE | MANUAL
ON_TEST_END(test):
IF auto_closing_level == TEST:
FOR EACH context created during test:
CLOSE context (and all its pages)
ON_SUITE_END(suite):
IF auto_closing_level == SUITE:
FOR EACH context created during suite:
CLOSE context (and all its pages)
# MANUAL: nothing happens automatically
CLOSE_BROWSER(selector):
IF selector == ALL:
CLOSE all browser processes
CLEAR all tracking state
ELIF selector == CURRENT:
CLOSE current active browser (and all its contexts/pages)
SET active browser to the previously active one
ELSE:
SWITCH TO browser matching selector
CLOSE that browser
RUN_ON_FAILURE:
# Maintained as a SettingsStack with Global/Suite/Test scopes
KEYWORD_EXECUTION_WRAPPER(keyword, args):
TRY:
EXECUTE keyword(args)
CATCH error:
IF NOT currently_running_failure_handler:
currently_running_failure_handler = True
failure_keyword = scope_stack["run_on_failure"].current()
IF failure_keyword IS NOT NONE:
TRY:
EXECUTE failure_keyword
CATCH failure_handler_error:
LOG warning: failure handler itself failed
FINALLY:
currently_running_failure_handler = False
RAISE error # Always re-raise the original error
REGISTER_KEYWORD_TO_RUN_ON_FAILURE(keyword, args, scope):
old_keyword = current run_on_failure keyword
new_keyword = PARSE(keyword, args)
scope_stack["run_on_failure"].set(new_keyword, scope)
RETURN old_keyword # For later restoration