Implementation:MarketSquare Robotframework browser Settings Stack
| Knowledge Sources | |
|---|---|
| Domains | Configuration Management, Scope Management |
| Last Updated | 2026-02-12 05:40 GMT |
Overview
Scoped settings stack that manages library configuration values (such as timeout and retry assertions) across Global, Suite, and Test scopes using an ordered dictionary-based stack.
Description
The module defines two classes. ScopedSetting is a dataclass that pairs a Scope enum value (Global, Suite, or Test) with an arbitrary setting value. SettingsStack maintains an ordered dictionary (_stack) keyed by scope identifiers, where the last entry always represents the currently active setting. The stack is initialized with a global-level setting and a reference to the Browser library context.
When a new scope starts (via start), the current top setting is inherited by the new scope. When a scope ends (via end), the entry is removed and if the setting changed, an optional setter_function callback is invoked to propagate the change (e.g., updating the Node.js side timeout). The set method applies a new setting at a given scope level: Global scope updates all entries in the stack, Suite scope replaces or adds a suite-level entry, and Test scope adds a test-level entry (only valid when a test case is running). The get method returns the current active setting value from the top of the stack.
Usage
Use SettingsStack to manage any Browser library configuration value that should respect Robot Framework's Global/Suite/Test scoping semantics. Instantiate it once per configuration key (e.g., timeout), pass the global default and the Browser library instance, and optionally provide a setter callback that propagates changes to the backend. Robot Framework listener hooks call start and end as suites and tests begin and complete.
Code Reference
Source Location
- Repository: MarketSquare_Robotframework_browser
- File: Browser/utils/settings_stack.py
- Lines: 1-76
Signature
@dataclass
class ScopedSetting:
typ: Scope
setting: Any
class SettingsStack:
def __init__(self, global_setting: Any, ctx: "Browser", setter_function: Callable | None = None): ...
def start(self, identifier: str, typ: Scope) -> None: ...
def end(self, identifier: str) -> None: ...
def set(self, setting: Any, scope: Scope | None = Scope.Global) -> Any: ...
def get(self) -> Any: ...
Import
from Browser.utils.settings_stack import SettingsStack, ScopedSetting
I/O Contract
| Method | Input | Output | Description |
|---|---|---|---|
| __init__ | global_setting: Any, ctx: Browser, setter_function: Callable or None | SettingsStack instance | Initializes the stack with a global-level entry keyed as "g" |
| start | identifier: str, typ: Scope | None | Pushes a new scope entry inheriting the current top setting value |
| end | identifier: str | None | Pops the scope entry; calls setter_function if setting reverted |
| set | setting: Any, scope: Scope or None | Any (previous value) | Applies a setting at the specified scope level; returns the previous value |
| get | None | Any | Returns the setting value from the top of the stack |
| Scope Behavior |
|---|
| Global -- Updates the setting value in every entry of the stack |
| Suite -- Replaces or adds a suite-level entry (pops test-level if present) |
| Test -- Adds a test-level entry; raises ValueError if no test case is running |
Usage Examples
from Browser.utils.settings_stack import SettingsStack
from Browser.utils.data_types import Scope
# Initialize with a 30-second global timeout
timeout_stack = SettingsStack(
global_setting=30000,
ctx=browser_instance,
setter_function=lambda val: grpc_set_timeout(val),
)
# Suite starts - inherits global timeout
timeout_stack.start("suite-001", Scope.Suite)
# Override timeout at suite level
previous = timeout_stack.set(10000, Scope.Suite)
# previous == 30000
# Get current timeout
current = timeout_stack.get()
# current == 10000
# Suite ends - reverts to global timeout, calls setter_function
timeout_stack.end("suite-001")