Principle:MarketSquare Robotframework browser Page State Assertion
| Property | Value |
|---|---|
| Principle Name | Page State Assertion |
| Domains | Test_Automation, Assertion |
| Workflow | Browser_Test_Authoring |
| Repository | MarketSquare/robotframework-browser |
| Type | Principle |
Overview
The inline assertion pattern combines value retrieval and verification into a single keyword call with automatic retry polling, eliminating the need for separate "get" and "assert" steps.
Description
The Page State Assertion principle defines a pattern where getter keywords (keywords that retrieve values from the page) optionally accept assertion parameters that verify the retrieved value inline. This pattern is a core design decision of the Browser library that provides several advantages over the traditional two-step approach.
Traditional approach (two steps):
value = GET_VALUE(selector)
ASSERT value == expected
Inline assertion approach (one step):
value = GET_VALUE(selector, operator="==", expected="expected_value")
The inline approach is superior for browser testing because it enables automatic retry polling. When an assertion is provided, the getter keyword uses the with_assertion_polling decorator to repeatedly:
- Retrieve the current value from the page
- Compare it against the expected value using the specified operator
- If the assertion fails and time remains, wait briefly (10ms) and retry
- If the assertion succeeds, return the value immediately
This retry mechanism is governed by two timeouts:
- timeout: The maximum total time to wait for the element and its value (configured at library import, default 10s).
- retry_assertions_for: The maximum time to retry assertion polling after the first failure (configured at library import, default 1s).
Supported Assertion Operators:
| Operator | Aliases | Description |
|---|---|---|
== |
equal, should be | Value equals expected |
!= |
inequal, should not be | Value does not equal expected |
contains |
*= | Value contains expected substring |
not contains |
Value does not contain expected substring | |
starts |
^= | Value starts with expected |
ends |
$= | Value ends with expected |
matches |
Value matches expected regex pattern | |
evaluates |
then | Evaluate a Python expression with the value |
> |
greater than | Value is greater than expected |
< |
less than | Value is less than expected |
>= |
greater than or equal | Value is greater than or equal to expected |
<= |
less than or equal | Value is less than or equal to expected |
When no assertion operator is provided, the keyword simply returns the value without any verification, behaving as a pure getter.
Usage
Use this principle when:
- You need to verify that page content matches expected values.
- You are dealing with dynamic content that may not be immediately available (AJAX updates, animations, delayed rendering).
- You want concise, readable test cases that combine retrieval and verification.
- You need tolerance for timing variability without adding explicit waits.
Theoretical Basis
GET_WITH_ASSERTION(selector, assertion_operator, assertion_expected, message):
# The with_assertion_polling decorator wraps this logic
start_time = NOW()
retries_start = None
timeout = global_timeout
retry_until = global_retry_assertions_for
LOOP:
TRY:
value = RETRIEVE_VALUE_FROM_PAGE(selector)
IF assertion_operator IS NOT None:
VERIFY(value, assertion_operator, assertion_expected, message)
RETURN value
CATCH AssertionError AS error:
IF retries_start IS None:
retries_start = NOW()
elapsed_total = NOW() - start_time
elapsed_retries = NOW() - retries_start
IF elapsed_total >= timeout OR elapsed_retries >= retry_until:
RAISE error # Final failure after exhausting retries
SLEEP(10ms) # Brief pause before retry
CONTINUE LOOP
VERIFY(value, operator, expected, message):
SWITCH operator:
CASE "==": ASSERT value == expected
CASE "!=": ASSERT value != expected
CASE "contains": ASSERT expected IN value
CASE "starts": ASSERT value STARTS WITH expected
CASE "ends": ASSERT value ENDS WITH expected
CASE "matches": ASSERT value MATCHES regex(expected)
CASE ">": ASSERT value > expected
CASE "<": ASSERT value < expected
CASE ">=": ASSERT value >= expected
CASE "<=": ASSERT value <= expected
CASE "evaluates": ASSERT eval(expected, {"value": value})