Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Principle:MarketSquare Robotframework browser Response Formatting and Validation

From Leeroopedia

Response Formatting and Validation

Transforming raw HTTP response data into structured, queryable objects in Robot Framework Browser.

Overview

When the Robot Framework Browser library receives HTTP responses (from the HTTP keyword or from intercepted network traffic via Wait For Response), the raw data must be transformed from wire-format strings into structured Python objects that Robot Framework tests can easily query and assert against. This transformation process involves JSON auto-parsing, header dictionary conversion, and DotDict wrapping to enable Robot Framework's dot-notation variable access.

Core Concept

HTTP responses travel through multiple layers before reaching the test:

  1. The browser's JavaScript fetch() API or Playwright's response listener captures the raw response.
  2. The Node.js Playwright wrapper serializes the response data as JSON, including stringified headers and a text body.
  3. The data crosses the gRPC boundary as a JSON string.
  4. The Python side deserializes the JSON and applies formatting transformations.

The formatting step is critical because the raw gRPC payload contains headers as a JSON-encoded string (not a dictionary) and response bodies as raw text (not parsed JSON). Without formatting, tests would need to manually parse these values in every assertion.

JSON Auto-Parsing

The library automatically detects JSON response bodies and parses them into Python dictionaries. This detection is based on the Content-Type header:

  1. The response headers are examined (case-insensitively) for a Content-Type header.
  2. If the Content-Type contains application/json, the body is parsed via json.loads().
  3. If parsing succeeds, the body is replaced with the resulting Python dictionary.
  4. If parsing fails (malformed JSON), the body is left as a plain string.

This auto-parsing applies to both:

  • The response body (the body key in the response dictionary).
  • The request postData (the postData key in the nested request dictionary, when present in Wait For Response results).

Header String-to-Dict Conversion

Headers arrive from the Node side as a JSON-encoded string (e.g., '{"content-type": "application/json", "x-request-id": "abc"}'). The formatting process parses this string into a Python dictionary, making individual header values accessible.

This conversion applies at two levels:

  • The response headers are converted from string to dictionary.
  • The request headers (within the nested request sub-dictionary) are also converted.

DotDict Wrapping

After formatting, the response dictionary is wrapped in Robot Framework's DotDict (from robot.utils). This enables dot-notation access in Robot Framework variables, which is substantially more readable than dictionary bracket syntax:

# With DotDict wrapping (clean):
Should Be Equal As Integers    ${response.status}    200
Should Be Equal    ${response.body.user.name}    John

# Without DotDict (verbose):
${status}=    Get From Dictionary    ${response}    status
Should Be Equal As Integers    ${status}    200
${body}=    Get From Dictionary    ${response}    body
${user}=    Get From Dictionary    ${body}    user
${name}=    Get From Dictionary    ${user}    name
Should Be Equal    ${name}    John

The DotDict wrapping enables nested access through dot notation, so ${response.body.user.name} traverses through the response body's user object to the name field. This works because when the body is JSON-parsed, nested dictionaries are also accessible via dot notation through DotDict's recursive attribute access.

Transformation Pipeline

The complete transformation pipeline for an HTTP response is:

  1. Raw gRPC response: JSON string containing stringified headers and text body.
  2. JSON deserialization: json.loads(response.json) produces a Python dictionary with string-valued headers and body.
  3. Response formatting (_format_response):
    • Headers are parsed from JSON string to dictionary.
    • Body is conditionally parsed from JSON string to dictionary (if Content-Type is application/json).
    • If a request sub-dictionary exists, its headers and postData receive the same treatment.
  4. DotDict wrapping: The formatted dictionary is wrapped in DotDict for dot-notation access.
  5. Fallback: If DotDict wrapping fails (e.g., the response is not a standard dictionary), the raw formatted value is returned.

Error Handling

The formatting process is designed to be fault-tolerant:

  • JSON parsing errors during body auto-parsing are suppressed (via contextlib.suppress). If the body looks like it should be JSON (based on Content-Type) but cannot be parsed, it remains as a string.
  • Header parsing errors default to an empty dictionary (json.loads(data.get("headers", "{}"))).
  • DotDict wrapping errors are caught, and the raw dictionary is returned with a debug log message.

Domains

Implemented By

Related

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment