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 Keyword Method Implementation

From Leeroopedia

Keyword Method Implementation

Overview

In robotframework-browser, test automation keywords are defined as decorated Python methods on classes that inherit from LibraryComponent. The @keyword decorator marks a method as a Robot Framework keyword, making it discoverable by the framework's dynamic library protocol. This pattern applies identically to both built-in keyword modules and plugin classes.

Core Concept: Methods as Keywords

Robot Framework's dynamic library API allows a library to report its keywords at runtime rather than relying on static introspection. The DynamicCore base class (from robotlibcore) scans all registered components for methods decorated with @keyword and exposes them to Robot Framework.

A keyword method is simply a Python method with:

  • A @keyword decorator (from either robot.api.deco or Browser.utils)
  • A descriptive docstring (used for keyword documentation)
  • Type-annotated parameters (used for automatic type conversion)
  • A return value (available in Robot Framework as the keyword's return value)
from robot.api.deco import keyword

class MyPlugin(LibraryComponent):

    @keyword
    def my_keyword(self, selector: str, timeout: timedelta = None) -> str:
        """Returns the text content of the element matching the selector."""
        resolved = self.resolve_selector(selector)
        # ... implementation ...
        return result

The @keyword Decorator

The decorator serves multiple purposes:

Attribute Purpose Example
name Override the keyword name (default: derived from method name) @keyword(name="Get Element Text")
tags Attach tags for filtering and categorization @keyword(tags=("Getter", "Element"))
types Override automatic type detection @keyword(types={"timeout": timedelta})

The robotframework-browser library provides its own keyword function in Browser/utils/misc.py that is a lightweight wrapper setting robot_name, robot_tags, and robot_types attributes on the decorated function. Both the standard robot.api.deco.keyword and the library's custom Browser.utils.keyword work for plugins.

Three Interaction Patterns

Keyword methods in plugins can interact with the browser through three distinct patterns:

Pattern 1: Direct gRPC Communication

The plugin opens a gRPC channel to the Node.js Playwright process and invokes a Playwright operation directly via protobuf messages:

@keyword
def new_plugin_cookie_keyword(self) -> dict:
    """Uses gRPC to directly call the Node.js side."""
    with self.playwright.grpc_channel() as stub:
        response = stub.GetCookies(Request().Empty())
        cookies = json.loads(response.json)
    return {"name": cookies[0]["name"], "value": cookies[0]["value"]}

This pattern gives full control over the Playwright protocol but requires knowledge of the gRPC service definition and protobuf message types.

Pattern 2: Calling Existing Library Keywords

The plugin calls methods on self.library, which is the fully initialized Browser instance. This allows reuse of existing keyword logic:

@keyword
def get_location_object(self) -> dict:
    """Calls the existing Evaluate Javascript keyword."""
    location_dict = self.library.evaluate_javascript(None, "window.location")
    return DotDict(location_dict)

This is the simplest pattern -- it composes higher-level behavior from existing keywords without needing to understand gRPC or protobuf details.

Pattern 3: Calling JavaScript Extensions

The plugin loads a JavaScript file and calls its exported functions. The JavaScript runs in Node.js with access to Playwright objects:

# In __init__:
self.initialize_js_extension(Path(__file__).parent / "myplugin.js")

# As a keyword:
@keyword
def mouse_wheel(self, x: int, y: int):
    """Calls a custom JavaScript keyword."""
    return self.call_js_keyword("mouseWheel", y=y, x=x)

This pattern bridges Python and JavaScript, enabling direct DOM manipulation or access to Playwright APIs not exposed through gRPC.

Method Naming and Keyword Names

By default, Robot Framework derives the keyword name from the Python method name using these rules:

  • Underscores become spaces: get_location_object becomes Get Location Object
  • The name is case-insensitive in Robot Framework test files

The name parameter of the @keyword decorator overrides this default. For plugins, using explicit names is recommended when the desired keyword name does not follow simple underscore-to-space conversion.

Type Annotations and Automatic Conversion

Robot Framework performs automatic type conversion based on Python type annotations. When a keyword parameter is annotated with a type, Robot Framework converts the string argument from the test file to that type:

Annotation Input (string) Converted Value
int "42" 42
bool "true" True
timedelta "5s" timedelta(seconds=5)
Enum subclass "value_name" EnumClass.value_name

This is particularly important for Browser library keywords that accept timedelta for timeouts, enum types for selectors and states, and complex types like dict for configuration objects.

Automatic Plugin Tagging

All keywords that originate from a plugin class are automatically tagged with "Plugin". This is handled by the Browser.get_keyword_tags() method at Browser/browser.py lines 1301-1305:

def get_keyword_tags(self, name: str) -> list:
    tags = list(DynamicCore.get_keyword_tags(self, name))
    if name in self._plugin_keywords:
        tags.append("Plugin")
    return tags

This means plugin authors do not need to manually add the "Plugin" tag -- it is injected automatically by the library.

Docstrings as Documentation

The docstring of a keyword method becomes the keyword's documentation in Robot Framework's libdoc output and in IDE autocompletion. Use reStructuredText or plain text formatting in docstrings. The first line should be a concise summary, with additional details in subsequent paragraphs.

Domains

Implemented By

Related

Page Connections

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