--- URL: "/" LLMS_URL: "/index.md" layout: "home" hero: name: "RobotCode" text: "The complete Robot Framework toolkit" image: src: "/robotcode-toy-tray.png" alt: "RobotCode Logo" actions: - theme: "brand" text: "Get Started" link: "/02_get_started" - theme: "alt" text: "Install VS Code" link: "https://marketplace.visualstudio.com/items?itemName=d-biehl.robotcode" - theme: "alt" text: "Install JetBrains" link: "https://plugins.jetbrains.com/plugin/26216" - theme: "alt" text: "Star on GitHub" link: "https://github.com/robotcodedev/robotcode" - theme: "alt" text: "Sponsor" link: "/#sponsor-robotcode" features: - icon: "🧠" title: "Code intelligence" details: "Context-aware completion for keywords (incl. embedded args), variables, libraries and resources. Hover docs, go-to-definition, find references, signature help, and live diagnostics β€” all powered by Robot Framework's own parser. Optional Robocop integration adds further linting and formatting checks on top.\n" link: "/01_about" linkText: "Learn more" - icon: "✏️" title: "Project-wide refactoring" details: "Rename keywords, arguments, variables and files safely across your entire workspace, including resources, libraries and multi-root setups. Preview every change before applying it.\n" link: "/01_about" linkText: "Learn refactoring" - icon: "🐞" title: "Run, debug & test explorer" details: "Discover and run tests from the editor's test panel or the CLI. Set breakpoints, step through keywords, inspect variables via the Debug Adapter Protocol, and jump straight to failures.\n" link: "/02_get_started" linkText: "Get Started" - icon: "βš™οΈ" title: "One config everywhere" details: "A unified robot.toml with profiles for dev, staging, CI, OS-specific or browser-specific setups. Editor, CLI and CI all read the same configuration β€” what works locally works in CI.\n" link: "/03_reference/config" linkText: "robot.toml reference" - icon: "🧰" title: "Powerful CLI" details: "A complete command-line interface for running, discovering, analyzing and inspecting Robot Framework projects. Every command is project-aware, JSON-friendly, and CI-ready.\n" link: "/03_reference/cli" linkText: "CLI reference" - icon: "πŸ““" title: "REPL & notebooks" details: "Try keywords interactively with robotcode repl or work in .robotbook files with a Jupyter Notebook-style UI. Great for experimentation, demos, and debugging snippets.\n" link: "/03_reference/cli#repl" linkText: "REPL docs" - icon: "🧩" title: "Multi-IDE, same core" details: "One Robot Framework language server powers VS Code, JetBrains, Neovim, Sublime Text and any LSP-capable editor. Choose your IDE β€” capabilities stay aligned.\n" link: "/01_about" linkText: "IDE overview" - icon: "🀝" title: "Open source, built with the community" details: "Free and open source β€” developed in close collaboration with the Robot Framework Core team and a worldwide community of testers, developers, and contributors.\n" link: "https://github.com/robotcodedev/robotcode" linkText: "GitHub" --- ## See RobotCode in Action ![Code Completions](/autocomplete1.gif) *Code completions for keywords, arguments and variables in the editor.* --- ![Running tests](/running_tests.gif) *Running tests right from the editor.* ## Watch: RoboCon 2024 tutorial This recorded RoboCon 2024 tutorial walks through the core features of RobotCode and demonstrates how to integrate the Language Server into your daily Robot Framework workflow. - Length: ~2 hours. - Level: Beginner to intermediate β€” basic familiarity with Robot Framework and a working Python environment is recommended. What you will learn: - How to install and enable the RobotCode extension for VS Code and JetBrains. - How the Language Server provides completion, hover documentation, and signature help to speed up test authoring. - Running and debugging tests from the editor, setting breakpoints, and inspecting variables during execution. - Using the built-in REPL and test discovery features to explore and iterate quickly. - and many more... ## Sponsor RobotCode **Individual:** - [GitHub Sponsors](https://github.com/sponsors/robotcodedev) – monthly or one-time - [Open Collective](https://opencollective.com/robotcode) – one-time or recurring **Corporate:** - [Open Collective](https://opencollective.com/robotcode) – direct, transparent, invoices, public ledger - [Robot Framework Foundation membership](https://robotframework.org/foundation/) – ecosystem support, indirectly benefits RobotCode See [Support & Contribute](/05_contributing/) for non-financial ways to help β€” bug reports, PRs, community help, and more. ## Powered by [![imbus AG](images/imbus-web-logo.svg)](https://www.imbus.de) [![Robot Framework Foundation](images/RFFoundation.svg)](https://robotframework.org/foundation) [![JetBrains Logo](images/jetbrains.svg)](https://jb.gg/OpenSourceSupport) --- URL: "/01_about" LLMS_URL: "/01_about.md" --- # What is RobotCode? **RobotCode** Is a set of tools and extensions and plugins for working with [Robot Framework](https://robotframework.org/) in different IDEs, editors and on the command line. **Built on Robot Framework Core** RobotCode is based on the Robot Framework Core and uses its parser, ensuring complete compatibility and consistency. This means you get the same syntax validation, error messages, and behavior as if you were running Robot Framework directly. **Powered by the Language Server Protocol** RobotCode is built on the Language Server Protocol (LSP), a modern standard for implementing language support across multiple editors and IDEs. This ensures a seamless and responsive user experience, while making it easier to maintain compatibility with evolving IDE features. **Extensions for Visual Studio Code and the IntelliJ Platform** RobotCode is available for Visual Studio Code, IntelliJ Platform. This ensures that you can use the same features and tools across different IDEs and editors. Because the extensions are based on the same codebase, you can expect the same level of quality and features across all platforms. (Because it is based on the Language Server Protocol, it is also possible to use it in other editors that support the LSP, like Neovim, Sublime Text, and more.) **Powerful Command Line Tools** RobotCode extends the Robot Framework CLI with enhanced tools for test execution, code analysis and debugging. It supports [`robot.toml`](https://robotcode.io/03_reference/) configurations, integrates a Debug Adapter Protocol (DAP) compatible debugger, and provides an interactive REPL environment for experimenting with Robot Framework commands. Modular and flexible, these tools streamline your workflow for both development and production. ## Key Features ### Autocomplete and IntelliSense - **Comprehensive Autocompletion:** Say goodbye to tedious typing! RobotCode provides autocompletion for libraries, resources, variables, and keywords, ensuring you always have the right tools at your fingertips. This includes support for local variables, resources, file-based variables (like Python and YAML), and command line variables, both static and dynamic. - **Context-Aware Suggestions:** IntelliSense offers context-sensitive suggestions, helping you code faster with fewer errors. It’s perfect for those moments when you can’t quite remember the exact syntax. ![Autocomplete Libraries and Keywords](images/autocomplete1.gif) ### Code Navigation - **Quick Symbol Navigation:** Easily move through your code with RobotCode’s symbol navigation, allowing you to jump straight to definitions, implementations, or references for keywords, variables, libraries, and resources. - **Error and Warning Diagnostics:** Stay on top of your code quality with real-time diagnostics that highlight errors and warnings as you code, so you can fix issues before they escalate. ### Diagnostics and Linting - **Real-Time Code Analysis:** RobotCode continuously monitors your code for syntax errors, unknown keywords, and issues with library or resource imports. This proactive approach helps you catch and resolve problems early in the development process. - **Seamless Integration with Robot Framework:** RobotCode uses the version of Robot Framework installed in your environment for diagnostics, ensuring accuracy and consistency with your actual test runs. - **Enhanced Linting with Robocop:** For developers who want to go further, RobotCode integrates with [Robocop](https://robocop.readthedocs.io/) to provide even more detailed analysis and linting, giving you insights into how to optimize your code. ### Code Formatting and Tidying - **Automatic Code Formatting:** Keep your code clean and consistent with RobotCode’s formatting tools. Use [Robocop's formatter](https://robocop.readthedocs.io/) for modern, consistent formatting directly in RobotCode. - **Customizable Formatting Options:** Tailor the formatting rules to suit your project’s needs, ensuring that your codebase remains consistent and easy to read. ### Running and Debugging - **Integrated Testing and Debugging:** RobotCode allows you to run and debug your Robot Framework test cases directly from within Visual Studio Code. This tight integration means you can execute tests, set breakpoints, and step through code without leaving the editor. - **Real-Time Log Navigation:** While debugging, RobotCode provides a live view of log messages in the debug console, allowing you to quickly identify and navigate to the source of any issues. ![Running Tests](images/running_tests.gif) ### Multi-root Workspace Support - **Manage Multiple Projects Seamlessly:** With support for [Multi-root Workspaces](https://code.visualstudio.com/docs/editor/multi-root-workspaces), RobotCode allows you to work on multiple Robot Framework projects simultaneously, each with its own settings and Python environments. Whether you prefer to have separate environments or share the same one across projects, RobotCode offers the flexibility to match your workflow. - **Smooth Workflow Transitions:** Easily switch between different projects and configurations without losing your place or context, making it easier to manage complex development environments and large codebases. ### Debug Adapter Protocol (DAP) Compatible Debugger - **Robust Debugging Capabilities:** RobotCode integrates a Debug Adapter Protocol (DAP) compatible debugger, enabling you to debug your Robot Framework tests with ease. Set breakpoints, step through code, inspect variables, and more, all from within your favorite editor. - Every IDE that supports the DAP can be used with RobotCode to debug Robot Framework tests. ### Robot Framework Repl and Notebooks - **Interactive REPL Environment:** Experiment with Robot Framework commands in an interactive Read-Eval-Print Loop (REPL) environment, perfect for testing out new ideas or troubleshooting issues on the fly. - **Jupyter Notebook-Like Experience:** Enjoy the flexibility of a Jupyter Notebook-like environment for working with Robot Framework code, allowing you to explore, test, and iterate quickly and efficiently. (direct integration with Jupyter Notebooks is planned for a future release.) ### Command Line Tools - **Enhanced Robot Framework CLI:** RobotCode extends the Robot Framework CLI with enhanced tools for test execution, code analysis, and debugging. ### Configure your Robot Framework environment with `robot.toml` - **Flexible Configuration Options:** RobotCode supports the use of [`robot.toml`](https://robotcode.io/03_reference/) configuration files, allowing you to customize your Robot Framework environment with ease. Define settings for test execution in the development, production, or testing environments, and switch between configurations effortlessly. - **Consistent Environment Management:** By using `robot.toml`, you can ensure that your Robot Framework settings are consistent across different projects and environments, reducing the risk of errors and simplifying the development process. - **Version Control Integration:** Store your `robot.toml` files in version control systems like Git, enabling you to share configurations with your team and maintain a history of changes over time. - **CI/CD Pipeline Integration**: Use `robot.toml` to define your test execution settings in CI/CD pipelines, ensuring that your tests run consistently across different environments and platforms. --- **RobotCode** isn’t just a toolβ€”it’s your coding partner. With its powerful features and seamless integration, RobotCode helps you be more productive and enjoy your coding experience. Whether you’re a seasoned Robot Framework user or just getting started, RobotCode is here to help you build, test, and deploy with confidence. Let's create something amazing together! --- URL: "/02_get_started" LLMS_URL: "/02_get_started.md" --- # Let's get started!!! Let's explore how you can enhance your development experience with RobotCode - Robot Framework for Visual Studio Code. We'll walk you through the steps of installing the RobotCode extension, configuring your environment, and ensuring smooth functionality. Get ready to unleash the power of RobotCode and Robot Framework in no time! ## Requirements - Python 3.10 or above - Robotframework version 5.0 and above - VSCode version 1.99 and above ## Tutorial Video If you prefer to watch a video tutorial, check out the following video that covers installing, setting up and using RobotCode in Visual Studio Code. Also check out the following video I gave at RoboCon 2024: ## Installing RobotCode To install RobotCode and set up your Robot Framework project in Visual Studio Code, follow these steps: 1. Open Visual Studio Code. 2. Go to the **Extensions** tab by pressing [[CONTROL+SHIFT+X]] or [[COMMAND+SHIFT+X]] on Mac 3. Search for **RobotCode** and install the [RobotCode - Robot Framework Support](https://marketplace.visualstudio.com/items?itemName=d-biehl.robotcode) extension. This will also install the **Python** and **Python Debugger** extensions. 4. *(Recommended)* Install the **Even Better TOML** extension for better handling of `.toml` files, which will be useful when configuring your project settings in the [Configuration](./configuration) section. ::: details Tip: Add to Workspace Recommendations (Optional) To ensure a consistent development environment for everyone working on this project, follow these steps: 1. Right-click on the RobotCode extension in the Extensions tab. 2. Click on **Add to Workspace Recommendations**. This will prompt all team members to install the RobotCode extension, creating a unified development environment. ![RobotCode](images/robotcode-add-to-workspace.gif) ::: See also the VSCode Documention on how to work with extensions [here](https://code.visualstudio.com/docs/editor/extension-marketplace). ## Setup a Robot Framework Project First you need to open your project folder in Visual Studio Code. You can do this by selecting **File > Open Folder** menu and navigating to the root folder of your project. If you don't have a project folder yet, you can also create a new folder in the "Open Folder" dialog. It is a good style to manage your project dependencies in a `requirements.txt` file. This file lists all the Python packages required for your project, including Robot Framework and any other dependencies you may need. This file can be used to install all the dependencies at once, ensuring that your project runs consistently across different environments. ::: tip Note However, it's important to note that there are alternative and better methods for setting up a Robot Framework project. Tools like [Hatch](https://hatch.pypa.io/) or [Poetry](https://python-poetry.org/) offer additional features and flexibility for managing project dependencies and environments. ::: Create a `requirements.txt` file in the root folder of your project and add the following content: ```txt [requirements.txt] robotframework ``` If you require additional dependencies, you can include them in the `requirements.txt` file. For instance, if you wish to utilize [robotframework-robocop](https://github.com/MarketSquare/robotframework-robocop) for formatting and linting your robot files and the [Browser library](https://robotframework-browser.org/) for website testing, you can add the following line to the `requirements.txt` file: ```txt [requirements.txt] robotframework robotframework-robocop robotframework-browser ``` ### Installing Dependencies ::: warning Depending on your requirements and system environment, it is advisable to avoid using the system python interpreter for development. Utilizing the system python interpreter can potentially cause conflicts with other projects or system dependencies. Instead, it is recommended to create a virtual environment for your project. Please refer to the [Creating a Virtual Python Environment](#creating-a-virtual-python-environment) section for detailed instructions. However, there are scenarios where using the system python interpreter is acceptable, such as when working with a docker container or a CI/CD pipeline. In such cases, you can skip the virtual environment setup and directly install the dependencies to the system python interpreter. If you want to use a virtual environment, please continue with the [Creating a Virtual Python Environment](#creating-a-virtual-python-environment) section. ::: To install the dependencies listed in the `requirements.txt` file, open the terminal in Visual Studio Code and run the following command: ```shell pip install -r requirements.txt ``` This command will install the Robot Framework and any other dependencies listed in the `requirements.txt` file. Make sure to run this command in the root folder of your project. #### Creating a Virtual Python Environment It is recommended to use a virtual python environment for your project to manage dependencies and ensure consistency across different environments. A virtual environment allows you to isolate your project's dependencies from the system-wide Python installation, ensuring that your project runs consistently across different environments. ::: details What is a Virtual Python Environment? A virtual environment is a self-contained directory that contains a Python installation along with all the necessary packages and dependencies for a specific project. Using a virtual environment is beneficial for several reasons: - Dependency management: By creating a virtual environment, you can easily manage and install project-specific dependencies without affecting other Python projects or the system-wide Python installation. - Version control: Including the virtual environment directory in your project's version control system ensures that all developers working on the project have the same environment setup, avoiding compatibility issues. - Reproducibility: With a virtual environment, you can recreate the exact environment in which your project was developed, making it easier to reproduce and debug issues. More informations about virtual environments can be found in the [Python documentation](https://docs.python.org/3/library/venv.html). ::: There are several ways to create a virtual Python environment and managing you project and project dependencies, depending on your preference and workflow. Below, we use the standard builtin python methods and describe two ways for creating a virtual environment: the "VSCode way" and the "Python way". Some other good options to manage your Robot Framework/Python environment are [hatch](https://hatch.pypa.io/), [poetry](https://python-poetry.org/) or [pipenv](https://pipenv.pypa.io/en/latest/) :::tabs === The VSCode way VSCode provides a built-in feature to create a virtual environment for your Robot Framework/ Python project. This feature allows you to create a virtual environment and install dependencies directly from the editor. You can also specify the Python version and include one or more `requirements.txt` files for managing project dependencies. You can refer to the [Python environments in VSCode Documentation](https://code.visualstudio.com/docs/python/environments) for more information. The short version of the steps are: 1. Open the Command Palette by pressing [[CONTROL+SHIFT+P]] or [[COMMAND+SHIFT+P]] on Mac, then search for `Python: Create Environment`, and select it. 2. Choose `Venv`, this will create a virtual environment in the `.venv` folder in your project. 3. Select your preferred Python version. 4. Check the box for requirements.txt and click OK. ![Create python environment](images/python-create-env.gif) === The Python way To create a virtual environment in Python, you can use the built-in `venv` module. This module provides a command-line interface as well as a Python API for managing virtual environments. Open a Terminal in VSCode and ensure you are in the root folder of your project. Then follow these steps: 1. Create a virtual environment: ``` python -m venv .venv ``` 2. Activate the virtual environment: ::: code-group ``` shell [Windows PowerShell/pwsh] myenv\Scripts\activate.ps1 ``` ``` shell [Windows CMD] myenv\Scripts\activate.cmd ``` ``` shell [Mac/Linux] source myenv/bin/activate ``` ::: 3. Install project-specific dependencies: ``` pip install -r requirements.txt ``` ::: ::: tip Remember to include the virtual environment directory `.venv` in your project's `.gitignore` file to avoid committing unnecessary files to your version control system. """ ::: ## Selecting the Python Interpreter After creating a virtual environment or if you want to switch to a different Python interpreter with Robot Framework installed for your project, you can select the Python interpreter in Visual Studio Code. This ensures that the correct Python environment is used for running your Robot Framework tests. To select the Python interpreter, follow these steps: 1. Open the Command Palette by pressing [[CONTROL+SHIFT+P]] or [[COMMAND+SHIFT+P]] on Mac. 2. Search for `Python: Select Interpreter` and select it. 3. Choose the Python interpreter associated with your virtual environment or the Python interpreter with Robot Framework installed. ## Verifying the Installation 1. Open the terminal in Visual Studio Code. You can do this by pressing [[CONTROL+`]] or selecting **Terminal > New Terminal** from the menu. If there is an existing terminal, you can close it and open a new one to ensure that the virtual environment is activated. 2. Run the command `robot --version` to check if Robot Framework is installed correctly. If the command returns the Robot Framework version number, your installation is successful! If you encounter any errors, ensure that your virtual environment is activated and that all dependencies in `requirements.txt` have been installed. ## Create and Run Your First Suite/Test Create a `first.robot` file in your project with the following code to demonstrate a basic example of logging a string message to the debug console: ```robot [first.robot] *** Test Cases *** First Test Case Log Hello world ``` To run this test file, press the green play button next to the `First Test Case` keyword in the code. You should see the `Hello world` output displayed in the **Debug Console** of Visual Studio Code. ![RobotCode](images/robotcode-first-test-case.gif) And that's it! If you have any questions or run into issues, check out the RobotCode documentation or join our community in slack for support. Happy coding! --- URL: "/02_get_started/configuration" LLMS_URL: "/02_get_started/configuration.md" --- # Configuration ## Introduction to the `robot.toml` File The `robot.toml` file serves as a centralized configuration system for your Robot Framework projects. Instead of managing multiple argument files, batch scripts, or command-line parameters, you can define all your project settings in one structured file. Similar to how `pyproject.toml` has become the standard for Python project configuration, `robot.toml` aims to provide the same benefits for Robot Framework projects by: - Centralizing all configuration in one location - Making settings easily shareable through version control - Supporting different environments through profiles - Providing a clear, readable format for configuration While fully compatible with development environments like VS Code, the `robot.toml` file is primarily designed to simplify Robot Framework project setup and maintenance. ## About TOML Files TOML (Tom's Obvious, Minimal Language) is a configuration file format designed to be easy to read and write. It uses simple key-value pairs organized into sections, making it more human-friendly than formats like JSON or XML. Example of TOML syntax: ```toml # This is a comment key = "value" [section] nested_key = "nested value" ``` For full details on TOML syntax, visit the [official TOML documentation](https://toml.io/en/). ## Basic Configuration ### Core Settings Every command-line option available in Robot Framework can be configured in your `robot.toml` file: ```toml # Basic settings output-dir = "output" log-level = "INFO" languages = ["en", "fi"] # Global variables [variables] BROWSER = "Chrome" LOGIN_URL = "https://example.com/login" TIMEOUT = "20s" ``` Multi-word options use hyphens in `robot.toml` (e.g., `--outputdir` becomes `output-dir`). To see all available options: - Run `robot --help` for standard Robot Framework options - Run `robotcode config info` for RobotCode-specific options - Check the [Configuration Reference](../03_reference/config.md) documentation ## Working with Profiles Profiles allow you to define multiple configurations for different environments or testing scenarios. ### Creating Basic Profiles ```toml # Default settings (applies to all profiles) output-dir = "results" log-level = "INFO" # Development environment profile [profiles.dev] output-dir = "results/dev" variables = { ENVIRONMENT = "development", API_URL = "http://dev-api.example.com" } # Production testing profile [profiles.prod] output-dir = "results/prod" variables = { ENVIRONMENT = "production", API_URL = "https://api.example.com" } ``` ### Profile Inheritance Profiles can inherit settings from other profiles to avoid duplication: ```toml # Base profile with common settings [profiles.base] log-level = "INFO" variables = { TIMEOUT = "20s" } # Development profile builds on base settings [profiles.dev] inherits = ["base"] variables = { ENVIRONMENT = "development", API_URL = "http://dev-api.example.com" } # Testing profile also builds on base settings [profiles.test] inherits = ["base"] variables = { ENVIRONMENT = "testing", API_URL = "http://test-api.example.com" } ``` ### Conditional Profiles Profiles can be hidden or enabled based on conditions: ```toml # Hidden profile (not shown in listings) [profiles.internal] hidden = true # Conditionally enabled profiles [profiles.windows] enabled.if = "platform.system() == 'Windows'" variables = { DRIVER_PATH = "C:\\drivers" } [profiles.linux] enabled.if = "platform.system() == 'Linux'" variables = { DRIVER_PATH = "/usr/local/bin" } ``` ### Profile Precedence When multiple profiles are used together, you can control which settings take priority: ```toml # Base settings (low precedence) [profiles.base] variables = { LOG_LEVEL = "INFO", BROWSER = "chrome" } # Override with higher precedence [profiles.debug] precedence = 100 variables = { LOG_LEVEL = "DEBUG" } # Highest priority settings [profiles.critical] precedence = 200 variables = { RETRIES = 3 } ``` ## Test Execution ### Running Tests with RobotCode To execute tests, install the `robotcode-runner` package: ```bash pip install robotcode[runner] ``` Common test execution commands: ```bash # Run all tests in a directory robotcode robot tests/ # Run with a specific profile robotcode -p dev robot tests/ # Combine multiple profiles robotcode -p base -p windows robot tests/ # Override variables on command line robotcode -p dev robot -v BROWSER:firefox tests/ # Run tests by tag robotcode robot -i smoke -i regression tests/ ``` You can also define paths directly in the configuration: ```toml paths = ["tests"] ``` then it is not needed to give specific paths at the commandline, just type: ```bash # run all tests robotcode run # run tests and only include/exclude tests with specific tags robotcode run -i regression -e wip ``` ## Advanced Configuration ### Extending vs. Replacing Settings By default, when merging profiles, list and dictionary settings are completely replaced. To add to these settings instead, use the `extend-` prefix: ```toml # Default settings variables = { BROWSER = "chrome", TIMEOUT = "20s" } include = ["smoke"] [profiles.api] # Completely replaces the default variables variables = { API_KEY = "123456" } # BROWSER and TIMEOUT are removed [profiles.extended] # Adds to the default variables extend-variables = { API_KEY = "123456" } # Results in {BROWSER = "chrome", TIMEOUT = "20s", API_KEY = "123456"} extend-include = ["api"] # Results in ["smoke", "api"] ``` Settings that support the `extend-` prefix include: - `variables` - `include` / `exclude` - `python-path` - `metadata` and many more, see the [`robot.toml` reference](../03_reference/config.md) for all posibilities. ## Configuration Loading Order RobotCode loads configuration files in a specific sequence, with each file potentially overriding settings from previous ones: 1. **Global user configuration** - Located at `~/.robot.toml` (user's home directory) - Sets system-wide defaults 2. **Project `pyproject.toml`** - Located in the project root - Robot settings stored in the `[tool.robot]` section 3. **Project `robot.toml`** - Located in the project root - Main project configuration (should be in version control) 4. **Personal `.robot.toml`** - Located in the project root - User-specific overrides (should be added to `.gitignore`) When multiple profiles are specified, they're applied in this order: 1. Default settings (top-level settings not in any profile) 2. Profiles ordered by precedence (lowest to highest) 3. For equal precedence, the order specified on the command line --- URL: "/03_reference" LLMS_URL: "/03_reference.md" --- # Reference This reference provides a comprehensive resource for effectively using and configuring the `robotcode` tool in Robot Framework projects. It covers the following areas: - [**Command Line Interface (CLI)**](cli.md): Detailed guidance on using the `robotcode` CLI to manage tasks such as test execution, code analysis, debugging, and configuration management directly from the command line. Each CLI command is explained with descriptions, options, and examples to illustrate different use casesβ€”from running tests in continuous integration (CI) environments to debugging specific test cases in development. - [**`robot.toml` Configuration File**](config.md): The `robot.toml` file serves as a centralized configuration for managing settings in Robot Framework projects in a structured, maintainable way. This section provides a complete guide to the available settings in `robot.toml`, including instructions on creating profiles for different environments, extending or inheriting settings, and managing variables, libraries, and dependencies across testing scenarios. With `robot.toml`, teams can efficiently handle project configurations, reduce redundancy, and simplify the setup of complex test environments. - [**Diagnostic Modifiers**](diagnostics-modifiers.md): Explains how to control static analysis diagnostics (errors, warnings, hints) using inline `# robotcode:` comments and configuration in `robot.toml`. It covers the available modifier actions, their scope within Robot Framework files, and how global and inline settings interact across CLI, language server, and editor integrations. - [**Analyzing Code**](analyzing-code.md): A task-oriented guide to the `robotcode analyze code` command β€” static analysis of a Robot Framework project without executing it. Covers the diagnostics it reports, severity remapping, exit codes and masks, the human-readable and machine-readable output formats (JSON, SARIF, GitHub annotations, GitLab Code Quality), and CI recipes for code scanning and build gating. - [**Analyzing Run Results**](analyzing-results.md): A task-oriented guide to the `robotcode results` family of commands β€” turning a finished run's `output.xml` into headline counts, per-test listings, full execution traces, tag/suite aggregations, and run-to-run diffs. Covers filtering, search, JSON-for-CI patterns, and the most common day-to-day recipes. - [**Discovering Tests, Tasks and Suites**](discovering-tests.md): A task-oriented guide to the `robotcode discover` family of commands β€” turning a project's source files into a tree, flat lists, tag indexes, or a file inventory without ever executing a test. Covers Robot-native and search filters, the `TestItem` JSON schema used by editor integrations, and CI recipes for sharding, tag reports, and parse-error gates. - [**Interactive Robot Framework REPL**](repl.md): A task-oriented guide to the `robotcode repl` command β€” a live keyword-driven shell for exploring libraries, prototyping snippets, debugging keyword behaviour and capturing ad-hoc sessions as a normal `output.xml` / `log.html`. Covers the prompt model, state persistence, file-execution and `--inspect` mode, output capture, and recipes for library exploration and CI smoke checks. - [**Command-line debugging**](robot-debug.md): A guide to the `robotcode robot-debug` command and the debugger attached to the `repl` shell β€” a command-line debugger for Robot Framework runs. Covers the ways to pause a run (line, keyword, embedded `Breakpoint`, exceptions, stop-on-entry), the debug command set (stepping, the call stack, inspecting and setting variables, breakpoint management, exception filters), and how it relates to the VS Code debugger. - [**Working with AI Agents**](ai-agents.md): How **RobotCode** lets AI coding agents (GitHub Copilot Chat, Claude Code, Codex, and other Open-Plugins-compatible tools) work through the project's own `robotcode` CLI instead of guessing. Covers the bundled VS Code chat plugin and its toggle, installing the plugin in other agents via the marketplace, what the agent is taught to do (discover, libdoc, REPL, results, analyze on the resolved project), and the CLI's AI-agent detection that keeps captured terminal output clean. Together, these sections provide the knowledge needed to fully customize `robotcode` for a flexible and efficient testing workflow. --- URL: "/03_reference/ai-agents" LLMS_URL: "/03_reference/ai-agents.md" --- # Working with AI Agents AI coding agents are good at writing code and bad at guessing how *your* Robot Framework project is actually wired. Which files become suites, which tags a test really ends up with, where a keyword comes from, what a finished run contained β€” none of that is reliably visible by reading `.robot` files. It is decided at runtime by `robot.toml`, profiles, variables, the installed library versions, and pre-run modifiers. **RobotCode** closes that gap by teaching the agent to work through the project's own [`robotcode`](cli.md) CLI instead of guessing. The agent discovers tests, runs suites, inspects results, looks up keywords, debugs failing tests at a real breakpoint, and explores live in the REPL β€” all through the same resolved view of the project that the rest of **RobotCode** uses. The result is an agent that behaves less like a generic code model and more like a Robot Framework engineer who knows your setup. There are two pieces, and they work independently: - **Chat plugins** (this page's main subject) β€” a RobotCode plugin that packages instructions for the agent. Today it ships a single *skill* that tells the agent *how* to use `robotcode`: which command answers which question, and which habits to avoid (don't grep for tests, don't load `output.xml` into the chat). The plugin is built to grow β€” more skills, agents, and other capabilities will ship in the same package. - **AI-agent detection** ([below](#ai-agent-detection)) β€” the CLI noticing it runs inside an agent session and quietly adjusting its terminal output for clean capture. **Who this is for:** - **Developers using GitHub Copilot Chat in VS Code** β€” the plugin ships with the extension and is on by default. - **Users of other agents** β€” Claude Code, Codex, GitHub Copilot CLI, and other [Open Plugins](https://open-plugins.com/)–compatible tools install the same plugin from a marketplace. - **Anyone scripting agents against Robot Framework projects** β€” the CLI's agent-aware output makes capture predictable. ## What you can ask Once the plugin is active, everyday Robot Framework requests are handled through the CLI with the right options, against your project's real configuration. For example: - *"run the smoke suite with the `ci` profile"* β€” runs it through the selected profile and reports pass/fail counts - *"rerun just the tests that failed last time"* - *"why did `Login Works` fail in last night's run?"* β€” inspects the existing results, no re-run - *"this test keeps failing β€” step through it and tell me what `${response}` is when it breaks"* β€” pauses the real run in the [debugger](robot-debug.md) and reads the live stack and variables, instead of re-running blindly or guessing - *"break at `login.robot:42` and show me the variables there"* - *"what tests and tags exist?"* β€” resolves the real set with `discover` (paths, profiles, variables, pre-run modifiers), not a file scan - *"what arguments does our `Create Order` keyword take?"* β€” looks it up against the installed libraries and local resources - *"is there already a keyword for waiting until the spinner is gone?"* - *"try the new login flow against the real app, with a visible browser"* β€” drives it live in the REPL (no test written yet) - *"set up a `prod` profile with `BASE_URL=https://prod.example.com`"* - *"lint only the files I changed today"* ## Prerequisites The chat plugin guides the agent in using `robotcode`; it does not bundle or replace the CLI. The [`robotcode` CLI tools](cli.md#installation) must be installed in the **project's** Python environment β€” not an isolated runner like `uvx` or `pipx`, which cannot see the project's libraries, resources, and local modules. If the CLI is missing, the agent is instructed to walk you through installing it (choosing scope and extras) before running anything. ## In VS Code (GitHub Copilot Chat) The VS Code extension bundles the RobotCode chat plugin for GitHub Copilot Chat. It is **enabled by default** β€” no installation step, no marketplace. The agent picks it up automatically and starts using `robotcode` whenever a request is about Robot Framework. You also don't need to install the `robotcode` CLI separately for this. The extension ships a bundled CLI β€” every subcommand included β€” and adds it to the integrated terminal's `PATH`; because Copilot Chat's agent runs its commands in that terminal, `robotcode` is available there out of the box. The bundle is only the *tool*, though: it runs against the terminal's active Python interpreter, so Robot Framework and your project's libraries still have to be installed in that environment for the CLI to inspect and run your project correctly. Toggle it with the setting: ```json "robotcode.ai.enableChatPlugins": true ``` Set it to `false` to turn the bundled plugin off β€” for example if you prefer to install the plugin from the marketplace instead (see the [duplication note](#avoiding-duplicates) below). ## Other agents β€” the marketplace The same plugin is published as an [Open Plugins](https://open-plugins.com/) marketplace, [`robotcodedev/robotframework-agent-plugins`](https://github.com/robotcodedev/robotframework-agent-plugins), so agents outside VS Code can install it once and reuse it. Supported agents include Claude Code, GitHub Copilot (CLI and Chat), and Codex; check [open-plugins.com/supported-agents](https://open-plugins.com/supported-agents) for the current list. Each agent uses its own commands to register a marketplace and install a plugin. For example: ```sh # Claude Code claude plugin marketplace add robotcodedev/robotframework-agent-plugins claude plugin install robotcode@robotframework-agent-plugins # GitHub Copilot CLI copilot plugin marketplace add robotcodedev/robotframework-agent-plugins copilot plugin install robotcode@robotframework-agent-plugins ``` See the [marketplace README](https://github.com/robotcodedev/robotframework-agent-plugins#install-per-agent) for the exact commands per agent, and for agents that load skill folders directly without a marketplace. ### Adding the marketplace from VS Code To use the marketplace version in VS Code's Copilot Chat (instead of, or alongside, the bundled plugin), the extension provides two Command Palette commands that edit the user-level `chat.plugins.marketplaces` setting for you: - **RobotCode: Add Chat Plugins Marketplace** - **RobotCode: Remove Chat Plugins Marketplace** Only the applicable one is shown at a time β€” *Add* until the marketplace is registered, *Remove* afterwards. (Removing also clears the entry if it was added by hand as a GitHub URL rather than the `owner/repo` shorthand.) The `chat.plugins.marketplaces` setting is owned by GitHub Copilot Chat, not by RobotCode, so these commands require Copilot Chat (or another agent that provides that setting) to be installed β€” without it, updating it fails with an error. ### Avoiding duplicates The bundled plugin and the marketplace plugin are the *same* plugin. If you install it from the marketplace, turn the bundled copy off so the agent doesn't load two identical plugins: ```json "robotcode.ai.enableChatPlugins": false ``` The *Add Chat Plugins Marketplace* command offers to do this for you when the bundled plugin is still enabled. ## How it works The plugin currently contains a single *skill* β€” a set of instructions the agent loads when a request looks Robot Framework–related β€” and is designed to gain more skills and agents over time. The skill calls no libraries or models of its own; it teaches the agent which `robotcode` command answers which question, and how to read the project the way Robot Framework does. The core habits it installs: - **Inventory via [`discover`](discovering-tests.md), never by grepping files.** Which tests, tasks, suites, and tags exist is resolved at runtime β€” Robot's parsing rules, `robot.toml` paths, profiles, variables, and pre-run modifiers that add, remove, rename, or retag tests. A static file scan gets it wrong; `discover` runs the real resolution with the installed Robot Framework. - **Keyword and library lookup via [`libdoc`](cli.md#libdoc), before generic knowledge.** `libdoc` reflects the *installed* library versions, the project's import arguments, the Python path, and local `.resource` files β€” things external documentation can't see. - **Debugging a failing test via [`robot-debug`](robot-debug.md) β€” the agent's primary tool for any real test.** Whenever an existing test fails, won't run, or needs stepping through, the agent runs it under the command-line debugger: it pauses the real suite at a breakpoint (a `file:line`, a keyword, or the first uncaught failure), then reads the live call stack and per-frame variables and runs keywords in the paused context β€” capturing the actual state at the point of failure instead of re-running blindly or reasoning from the source. This is the default response to "why does this fail / step through it / what is `${x}` here?", and it is deliberately kept apart from the REPL below: the debugger acts on a test that *exists and runs*. Reaching for the REPL to fix a real test β€” instead of the debugger β€” is the single most common way the skill misfires. - **Live exploration via the [REPL](repl.md) β€” only when there is *no* test yet.** A narrower tool: uncertain locators or keyword sequencing get tried interactively (optionally against the running app with a visible browser) rather than guessed. The moment a real test is in play, it is the debugger's job, not the REPL's. - **Result inspection via [`results`](analyzing-results.md), not raw `output.xml`.** Finished runs are queried for bounded summaries, listings, traces, and diffs β€” including CI artifacts and a colleague's run β€” rather than loading a potentially huge XML file into the chat. - **Static checks via [`analyze code`](analyzing-code.md)** before a run, and **runs via [`robot`](cli.md#robot)** honoring the active profile. Throughout, the agent respects the project's [`robot.toml`](config.md) and profiles, so it operates on the same resolved configuration as the editor and the CLI. ## Give the agent project context The skill teaches the agent *how* to drive `robotcode`, and `robotcode` resolves everything in your configuration at runtime β€” paths, profiles, tags, suites, installed library versions β€” so you never have to repeat that for the agent. What it **can't** infer is the surrounding setup and intent. Capturing those once in your agent's instructions file β€” `AGENTS.md` (an emerging cross-agent convention), `CLAUDE.md` for Claude Code, `.github/copilot-instructions.md` for GitHub Copilot, or whatever your agent reads β€” saves it from rediscovering them on every task and keeps it from guessing wrong. Worth recording: - **Environment & package manager** β€” which tool manages dependencies (`uv`, `hatch`, `poetry`, `pip`, …) and where the project's virtual environment lives, so the agent runs `robotcode` from the right interpreter (see [Prerequisites](#prerequisites)). - **Installed libraries and their setup steps** β€” especially any one-off initialization needed after an install or update. For example, Browser Library needs `rfbrowser init` to download its Playwright browsers before its keywords work; an agent that doesn't know this runs into confusing failures. - **The system under test** β€” what the application is, how to reach it (base URLs per environment, which profile points where), and any test data or accounts. Keep secrets out β€” describe *how* credentials are provided (env vars, a vault), not the values themselves. - **Project conventions** β€” naming, tags, suite layout, and where new keywords belong, so generated tests match what you already have. Keep it short and factual; this is standing context the agent reads on every request, not a place to duplicate `robot.toml`. ## AI-agent detection Independently of the chat plugins, the `robotcode` CLI detects when it is running inside an AI-agent session and adjusts its presentation defaults so captured output stays clean: - ANSI **colors** and the **pager** are disabled, so escape sequences and paging controls don't leak into the agent's captured stdout. - The [`robotcode robot-debug`](robot-debug.md) prompt and the [`robotcode repl`](repl.md) shell fall back to the **plain input backend**, so completion popups and prompt redraws don't interfere with stdin/stdout β€” captured debug output (`.where`, `.vars`, `.print`) stays clean. Detection is based on environment markers set by popular tools β€” Claude Code, Cursor, GitHub Copilot (CLI and VS Code agent flow), Codex, OpenCode, Gemini CLI, and others β€” plus the generic `AI_AGENT` and `AGENT` conventions. A marker counts as active when it is present with any value other than empty or `0`. You rarely need to touch this, but every default can be overridden: | Override | Effect | | --- | --- | | `ROBOTCODE_FORCE_AI_AGENT=1` | Force detection **on** (e.g. an agent whose marker isn't recognized yet). Wins over everything. | | `ROBOTCODE_NO_AI_AGENT=1` | Force detection **off**. Wins over tool markers, loses to `ROBOTCODE_FORCE_AI_AGENT`. | | `--color` / `--no-color`, `NO_COLOR`, `FORCE_COLOR` | Decide coloring explicitly, regardless of detection. | | `--pager` / `--no-pager` | Decide paging explicitly. | | `--plain` / `--backend`, `ROBOTCODE_REPL_PLAIN`, `ROBOTCODE_REPL_BACKEND` | Decide the prompt backend explicitly β€” applies to both `robot-debug` and the REPL. | Explicit flags and environment variables always win over auto-detection, so you can opt back into colored, paged, or full-featured output inside an agent session when you want it. ## Troubleshooting **The agent answers from generic knowledge instead of using `robotcode`.** A skill is loaded by *relevance* β€” the agent matches your request against the skill's description and only pulls it in when the request reads as Robot Framework work. A terse prompt in a mixed-language repo ("run it", "fix this test") may not trigger it. Name the domain β€” mention Robot Framework, a suite, a profile, a keyword, or `robotcode` itself β€” or invoke the skill explicitly by name (it's called **`robotcode`**). In VS Code, also confirm `robotcode.ai.enableChatPlugins` is `true` β€” see [In VS Code](#in-vs-code-github-copilot-chat). **The agent's answers don't match your project** β€” libraries or keywords it should see are reported as missing, or argument lists look wrong. It is most likely driving a `robotcode` from the wrong environment rather than the project's (see [Prerequisites](#prerequisites)). Have the agent run `robotcode discover info` to show which interpreter and versions it is using, and compare that against the project's environment. **The agent re-runs a failing test over and over (or pastes it into the REPL) instead of debugging it.** This is the skill's single most common misfire. When a *real* test fails, the right tool is the [debugger](robot-debug.md), not blind re-runs or the REPL β€” it pauses the actual run at the failure and exposes the live stack and variables. Tell it to debug the test ("step through it with `robot-debug`", "break where it fails and show me the variables"). The REPL is for exploring when there's no test yet; the debugger is for a test that already runs. **The agent writes a `.robot` file when you only wanted it to *do* something** β€” try a keyword or check a locator with no test yet. Tell it not to write a test and to use the REPL instead ("don't write a test, just run it live"); it can save the session as a test afterwards if you ask. See [Interactive Robot Framework REPL](repl.md). (If a test already exists, you want the debugger above, not the REPL.) **A marketplace install behaves differently from the bundled VS Code plugin.** The two copies are versioned independently: the bundled one ships with the extension, the marketplace one updates through your agent's `plugin marketplace update`. If behavior diverges, update the marketplace copy β€” and make sure you aren't running both at once (see [Avoiding duplicates](#avoiding-duplicates)). ## See also - [Command Line Interface](cli.md) β€” every `robotcode` command the agent drives. - [Discovering Tests, Tasks and Suites](discovering-tests.md) β€” how project inventory is resolved. - [Analyzing Run Results](analyzing-results.md) β€” inspecting finished runs. - [Command-line debugging with `robotcode robot-debug`](robot-debug.md) β€” pausing a real run at a breakpoint to inspect the live stack and variables. - [Interactive Robot Framework REPL](repl.md) β€” the live keyword shell. - [`robotframework-agent-plugins`](https://github.com/robotcodedev/robotframework-agent-plugins) β€” the marketplace and plugin source. --- URL: "/03_reference/analyzing-code" LLMS_URL: "/03_reference/analyzing-code.md" --- # Analyzing Code ::: tip Installation The `robotcode analyze` command comes from the optional **`analyze`** package. If it isn't installed yet, add it: ```bash pip install robotcode[analyze] # or: pip install robotcode[all] ``` ::: **`robotcode analyze code`** performs static analysis on a Robot Framework project: it parses the `.robot` and `.resource` files, resolves their imports, libraries, and variables, and reports diagnostics for problems such as unknown keywords, unresolved variables, wrong argument counts, duplicate or failing imports, and deprecated syntax. No tests are executed. The analysis is performed by the same code that powers the RobotCode language server, so the diagnostics are identical to the ones shown in the editor (the VS Code extension, the IntelliJ plugin, or any other LSP client); `analyze code` applies that analysis to the whole project from the command line. Configuration and profile resolution work the same as for `robotcode robot`, so imports and variables resolve as they would at run time. The result is printed as a human-readable list or, for CI use, as a structured report (JSON, SARIF, GitHub annotations, or GitLab Code Quality). Which diagnostics are reported, and at what severity, can be configured per project or inline in the source; this is shared with the language server and documented separately in [Controlling Diagnostics with Modifiers](diagnostics-modifiers.md). **Who this is for:** - **Developers** who want a fast "is my project sound?" check before committing or running anything. - **CI/CD pipelines** that want to fail a build on broken keyword references or upload findings to a code-scanning dashboard. - **Code review / security tooling** β€” the SARIF output plugs straight into GitHub code scanning; the GitLab format into Merge Request Code Quality widgets. - **AI-driven workflows** β€” a coding agent gets a precise, machine-readable list of what's wrong instead of having to run the suite and parse a traceback. This guide covers **`analyze code`**. The `analyze` group has one other subcommand, [`cache`](#managing-the-analysis-cache), for inspecting and clearing the on-disk analysis cache β€” covered briefly at the end. For the exhaustive, auto-generated option list see the [CLI reference](cli.md#code). ## Quick start ```bash # Analyze the current project (default paths from the active profile) robotcode analyze code # Analyze a specific folder or file robotcode analyze code tests/acceptance robotcode analyze code tests/acceptance/login.robot # Only look at certain files robotcode analyze code --filter "**/*.resource" # Also report unused keywords and variables robotcode analyze code --collect-unused # Treat a specific diagnostic as ignored / as an error robotcode analyze code -mi MultipleKeywords robotcode analyze code -me VariableNotFound # Machine-readable output robotcode analyze code --output-format json robotcode analyze code --output-format sarif --output-file robotcode.sarif ``` If you don't pass any paths, `analyze code` analyzes the **whole project** β€” every `.robot` / `.resource` file under the project root, minus the configured exclude patterns. (This is unlike `robotcode robot`, which would run only the default paths/suites from your profile.) ## How `analyze code` finds your project `analyze code` reuses the full RobotCode configuration pipeline: 1. It locates the project root and the `robot.toml` / `pyproject.toml` files the same way every other `robotcode` command does. 2. It applies the active **profile(s)** (`--profile`) and the `[tool.robotcode-analyze]` settings. 3. It honours `--variable`, `--variablefile` and `--pythonpath` (mirroring the corresponding `robot` options) so that imports and variable resolution behave exactly as they would at run time. This matters: a keyword that only resolves because of a `--pythonpath` entry or a variable file resolves during analysis too, instead of being wrongly reported as missing. The project's imports and libraries are always resolved up front, across the whole project β€” that part can't be narrowed. The per-file diagnostics are then computed only for the files selected by `paths` / `--filter`, so a narrower selection does make a run faster. ## What it checks The diagnostics are exactly those the language server produces. Among the most common: - **`KeywordNotFound`** β€” a keyword call that resolves to nothing. - **`MultipleKeywords`** β€” an ambiguous keyword name matching several definitions. - **`VariableNotFound`** / **`VariableNotReplaced`** β€” references to variables that don't exist or can't be resolved statically. - **import diagnostics** β€” `LibraryAlreadyImported`, `ResourceAlreadyImported`, `ImportContainsErrors`, circular imports, … - **deprecation warnings** β€” `DeprecatedReturnSetting`, `DeprecatedHeader`, `DeprecatedHyphenTag`, … - **model errors** β€” empty tests/keywords, invalid headers, and other structural problems. This is *static* analysis, so it isn't the last word: actually running the suite β€” or even discovering it with [`robotcode discover`](discovering-tests.md) β€” can surface errors that `analyze code` doesn't. Building the real test suite runs additional, suite-wide checks (for example duplicate test case names), and a `PreRunModifier` may have changed the suite before it's executed β€” neither of which the per-file static analysis sees. A clean `analyze code` result is a strong signal, not a guarantee that a run will start without errors. ### Unused keywords and variables By default `analyze code` does **not** flag unused definitions. Unlike the per-file diagnostics, deciding whether a keyword or variable is unused needs the reference data of the *whole* project β€” not just the selected files β€” so it can't take the `paths` / `--filter` shortcut, and it adds an extra pass that is noticeably slower on projects with many keywords and variables. Enable it explicitly: ```bash robotcode analyze code --collect-unused ``` This adds two diagnostics: - **`KeywordNotUsed`** β€” a keyword defined in the project that nothing references. - **`VariableNotUsed`** β€” a variable/argument that's never read. Names that are intentionally unused (`${_}`, `${_ignored}`) are skipped. They behave like any other diagnostic β€” you can remap or ignore them with the [modifiers](#severities-and-diagnostic-modifiers) (e.g. `-mh KeywordNotUsed`) or `# robotcode:` comments. You can also turn this on permanently in `robot.toml`: ```toml [tool.robotcode-analyze.code] collect_unused = true ``` ## Severities and diagnostic modifiers Every diagnostic has one of four severities β€” **Error**, **Warning**, **Information**, **Hint** β€” and you can remap any diagnostic code to a different severity (or silence it entirely). On the command line: | Flag | Effect | |---|---| | `-mi`, `--modifiers-ignore CODE` | Ignore this diagnostic code entirely | | `-me`, `--modifiers-error CODE` | Treat as **Error** | | `-mw`, `--modifiers-warning CODE` | Treat as **Warning** | | `-mI`, `--modifiers-information CODE` | Treat as **Information** | | `-mh`, `--modifiers-hint CODE` | Treat as **Hint** | Each flag can be given multiple times. The same mapping is available β€” and usually better kept β€” in `robot.toml`: ```toml [tool.robotcode-analyze.modifiers] ignore = ["VariableNotFound"] error = ["MultipleKeywords"] hint = ["KeywordNotUsed"] ``` `*` is a wildcard that matches every code, so `-mi "*"` silences all diagnostics. Re-introducing specific codes at a chosen severity then gives you an allow-list: ```bash # show only KeywordNotFound β€” reported as a warning robotcode analyze code -mi "*" -mw KeywordNotFound ``` This is a *remap* (the kept codes take the severity you assign). If you instead want to keep a code at its original severity, use the [`--code` filter](#reporting-only-some-diagnostics). Because the severity is configurable, the text and SARIF/GitHub/GitLab output always carries the **effective** severity, not a hard-coded one. For the full modifier system β€” including inline `# robotcode:` comments β€” see [Controlling Diagnostics with Modifiers](diagnostics-modifiers.md). ### Reporting only some diagnostics Two flags narrow the result to a subset. Unlike the modifiers above (which *remap* a code's severity), these *filter*: whatever you don't list is dropped from the output, the summary **and** the exit code alike β€” the severity of what remains is unchanged. - **`--severity`** β€” keep only the given severities. Values: `error`, `warn`/`warning`, `info`/`information`, `hint`. - **`--code`** β€” keep only the given diagnostic codes (e.g. `KeywordNotFound`); matching is case-insensitive. Both are repeatable and comma-separated. When both are given they combine with **AND** β€” a diagnostic must match both. ```bash robotcode analyze code --severity warning,hint # only warnings and hints robotcode analyze code --code KeywordNotFound # only KeywordNotFound, with its real severity robotcode analyze code --code KeywordNotUsed --severity hint # only KeywordNotUsed that are hints ``` When neither is given, everything is reported. ## Exit codes `analyze code` exits with a **bitwise combination** of these values, so a single status tells you which severities were present: | Bit | Value | Meaning | |---|---|---| | β€” | `0` | **SUCCESS** β€” nothing reported | | `1` | `ERRORS` | at least one error | | `2` | `WARNINGS` | at least one warning | | `4` | `INFOS` | at least one information | | `8` | `HINTS` | at least one hint | For example, errors **and** warnings give `1 | 2 = 3`. To stop certain severities from affecting the exit code β€” e.g. so warnings don't fail the build β€” use an **exit-code mask**: ```bash # Warnings/infos/hints no longer change the exit code; only errors do robotcode analyze code --exit-code-mask warn,info,hint # Same, but additive to the mask configured in robot.toml robotcode analyze code --extend-exit-code-mask hint ``` Valid mask values: `error`, `warn` (alias `warning`), `info` (alias `information`), `hint`, `all`. In `robot.toml`: ```toml [tool.robotcode-analyze.code] exit_code_mask = ["warn", "info", "hint"] # CI fails only on errors ``` Any non-zero exit means something was reported, which is what makes a CI step fail by default. To branch on a specific severity, test the corresponding bit β€” in bash: ```bash robotcode analyze code code=$? (( code & 1 )) && echo "errors present" (( code & 2 )) && echo "warnings present" ``` ## Output formats The local `--output-format` flag selects how results are rendered. It **overrides the global `--format`** for this command: | Value | Output | |---|---| | `concise` *(default)* | Human-readable list, one finding per line, sorted by `(file, line, column)` | | `json` | Compact structured result (`diagnostics` + `summary`) | | `json-indent` | Same, pretty-printed | | `sarif` | SARIF 2.1.0 log β€” for GitHub code scanning and other SARIF consumers | | `github` | GitHub Actions workflow annotations (`::error file=…`) | | `gitlab` | GitLab Code Quality report (JSON array) | `--output-file FILE` writes the report to a file instead of stdout (for the `json`, `json-indent`, `sarif`, `github` and `gitlab` formats) β€” handy for uploading a CI artifact. A missing target directory yields a clear error rather than a traceback. ```bash robotcode analyze code --output-format sarif --output-file reports/robotcode.sarif ``` ## Text output (`concise`) The default format prints one finding per line: ``` tests/login.robot:4:5: [ERROR] KeywordNotFound: No keyword with name 'Lgin User' found. tests/login.robot:7:1: [WARNING] KeywordNotUsed: Keyword 'Helper' is not used. Files: 12, Errors: 1, Warnings: 1, Infos: 0, Hints: 0 (in 0.42s) ``` - Each line is `path:line:column: [SEVERITY] Code: message`; the severity tag is colored (red/yellow/blue/cyan). - Output is **sorted by `(file, line, column)`**, so it's stable regardless of internal analysis order. - Workspace-level problems that aren't tied to a single file (e.g. a broken command-line variable file) are prefixed with `.:`. - Related locations are shown on indented `->` lines. - The summary line is colored after the highest severity present. By default RobotCode trims the Python traceback and `PYTHONPATH` listing that Robot Framework appends to import errors. Pass `--show-tracebacks` to keep the full message. ## SARIF `--output-format sarif` emits a [SARIF 2.1.0](https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/sarif-v2.1.0-errata01-os.html) log β€” the format GitHub code scanning, Azure DevOps and the VS Code SARIF Viewer consume. ```bash robotcode analyze code --output-format sarif --output-file robotcode.sarif ``` Paths are written relative to the project root, which is what GitHub code scanning expects (use `--full-paths` for absolute paths). Once uploaded, an alert stays stable as long as the finding does β€” an unrelated edit that merely shifts its line number won't create a duplicate. ## GitHub Actions annotations `--output-format github` emits [workflow annotations](https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-commands). Printed in a GitHub Actions job, they appear inline on the affected lines in the PR diff and in the run summary. ```bash robotcode analyze code --output-format github ``` Each diagnostic becomes one annotation line: ``` ::error file=tests/login.robot,line=4,col=5,endColumn=14,title=KeywordNotFound::No keyword with name 'Lgin User' found. ``` ## GitLab Code Quality `--output-format gitlab` emits a [Code Quality report](https://docs.gitlab.com/ci/testing/code_quality/) that GitLab renders in the Merge Request Code Quality widget. ```bash robotcode analyze code --output-format gitlab --output-file gl-code-quality.json ``` Each diagnostic becomes one entry in the JSON array: ```json [ { "description": "No keyword with name 'Lgin User' found.", "check_name": "KeywordNotFound", "fingerprint": "…", "severity": "major", "location": { "path": "tests/login.robot", "lines": { "begin": 4 } } } ] ``` ## CI recipes ### GitHub: upload to code scanning Produce a SARIF file and upload it so the findings appear under **Security β†’ Code scanning**. The `security-events: write` permission is required for the upload, and `continue-on-error` lets the upload run even when `analyze code` exits non-zero because it found problems. ```yaml name: RobotCode Analyze on: [push, pull_request] jobs: analyze: runs-on: ubuntu-latest permissions: security-events: write # required for upload-sarif steps: - uses: actions/checkout@v5 - uses: actions/setup-python@v6 with: python-version: "3.x" # Set up the project with whatever package manager it uses (pip, uv, # poetry, pdm, hatch, ...); analysis just needs robotcode[analyze] available. - run: pip install robotcode[analyze] - run: robotcode analyze code --output-format sarif --output-file robotcode.sarif continue-on-error: true - uses: github/codeql-action/upload-sarif@v4 with: sarif_file: robotcode.sarif ``` ### GitHub: inline PR annotations Print the `github` format directly β€” the diagnostics show up as inline annotations on the run and in the PR diff. No upload and no extra permissions needed. ```yaml name: RobotCode Analyze on: [push, pull_request] jobs: analyze: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - uses: actions/setup-python@v6 with: python-version: "3.x" # Set up the project with whatever package manager it uses (pip, uv, # poetry, pdm, hatch, ...); analysis just needs robotcode[analyze] available. - run: pip install robotcode[analyze] - run: robotcode analyze code --output-format github ``` ### GitLab: Code Quality artifact Write the GitLab report and expose it as a `codequality` artifact; GitLab renders it in the Merge Request Code Quality widget. ```yaml robotcode-analyze: image: python:3 script: # set up the project with whatever package manager it uses (pip shown here) - pip install robotcode[analyze] - robotcode analyze code --output-format gitlab --output-file gl-code-quality.json artifacts: reports: codequality: gl-code-quality.json ``` ### Fail the build on errors only ```bash # Exit non-zero only for errors; warnings/infos/hints are reported but ignored robotcode analyze code --exit-code-mask warn,info,hint ``` ### Get just the counts ```bash robotcode analyze code --output-format json | jq '.summary' ``` ## Managing the analysis cache To speed up repeat analysis, RobotCode caches resolved library/variable imports (and, with `--cache-namespaces`, analyzed namespaces) on disk. The `analyze cache` subcommands let you inspect and clear it: ```bash robotcode analyze cache info # where the cache lives and how big it is robotcode analyze cache list # what's cached robotcode analyze cache path # print the cache directory robotcode analyze cache clear # remove it (e.g. after changing ignored-libraries) robotcode analyze cache prune # drop stale entries only ``` Clearing the cache is the usual fix after changing cache-affecting settings such as `ignore-arguments-for-library`. ## Configuration via `robot.toml` Everything controllable on the command line (and more) lives under `[tool.robotcode-analyze]`: ```toml [tool.robotcode-analyze] exclude-patterns = ["**/generated/**"] global-library-search-order = ["MyPreferredLibrary"] load-library-timeout = 30 [tool.robotcode-analyze.code] collect_unused = true exit_code_mask = ["warn", "info", "hint"] [tool.robotcode-analyze.modifiers] ignore = ["VariableNotFound"] error = ["MultipleKeywords"] [tool.robotcode-analyze.cache] ignored-libraries = ["MyDynamicLibrary"] ``` See the [`robot.toml` configuration reference](config.md) for the complete list of settings. ## JSON reference `--output-format json` (or `json-indent`) emits a single object with two keys, using the same LSP `Diagnostic` shape as `robotcode discover` and `robotcode results`: ```json { "diagnostics": { "tests/login.robot": [ { "range": { "start": { "line": 3, "character": 4 }, "end": { "line": 3, "character": 13 } }, "message": "No keyword with name 'Lgin User' found.", "severity": 1, "code": "KeywordNotFound", "source": "robotcode" } ] }, "summary": { "files": 12, "errors": 1, "warnings": 0, "infos": 0, "hints": 0 } } ``` Field notes: - Keys in `diagnostics` are source paths (project-relative POSIX, or absolute with `--full-paths`). Workspace-level diagnostics key on `.`. - `severity` follows the LSP enum: `1` = Error, `2` = Warning, `3` = Information, `4` = Hint. - Positions are **0-based** (LSP convention), unlike SARIF/GitHub which are 1-based. - The JSON always carries the full diagnostic message β€” `--show-tracebacks` does not apply. - `summary` is always present, even for a clean run (all counts `0`), so consumers get a stable schema. --- URL: "/03_reference/analyzing-results" LLMS_URL: "/03_reference/analyzing-results.md" --- # Analyzing Run Results ::: tip Installation The `robotcode results` command comes from the optional **`runner`** package. If it isn't installed yet, add it: ```bash pip install robotcode[runner] # or: pip install robotcode[all] ``` ::: Every Robot Framework run leaves a result file behind that captures everything the run did β€” counts, statuses, messages, the per-test keyword tree, timing. `report.html` and `log.html` are the visual face of that data; **`robotcode results`** is the scriptable one. Same data, on the terminal or in a pipeline, without leaving the shell. **Who this is for:** - **Developers** triaging failures from the terminal β€” no need to open `report.html` in a browser every time something turns red. - **CI/CD pipelines** that need machine-readable status, regression gates, or per-suite/tag dashboards. The structured output is stable enough to script against. - **Teams** comparing runs across branches, builds or test agents β€” what got better, what got worse, what's new. - **AI-driven workflows** β€” coding agents (Claude Code, Cursor, Copilot, …), failure-analysis assistants, statistics interpretation, automated triage and reporting. Feeding raw `output.xml` into the agent's context is wasteful in any of these β€” multi-megabyte input the agent then has to figure out how to parse. `robotcode results` returns just the slice the workflow asked for (counts, failing tests, messages above a level). Typical things you can do with it: - check the headline status of the last run in one command - list just the failing tests, sorted by who took longest - walk a single test's execution log, with timestamps and extracted screenshots - aggregate results by tag or suite for reporting or dashboards - diff two runs and find regressions The five subcommands all read the same result file and share the same filter, search, and output-format options β€” once you've learned one the others follow: | Subcommand | Use it when you want to … | |---|---| | [`summary`](#summary-headline-numbers) | … see the headline counts and overall status | | [`show`](#show-list-individual-tests) | … list individual tests (with sort, filter, search) | | [`log`](#log-walk-the-execution-tree) | … inspect the per-test execution tree | | [`stats`](#stats-aggregate-by-tag-suite-or-status) | … aggregate by tag, suite, or status | | [`diff`](#diff-compare-two-runs) | … compare two runs and find new failures | This guide is split in two: 1. **[Part 1 β€” Using the commands](#quick-start)** walks through every subcommand from the terminal perspective: what each one does, what shows up on the screen, and what filters and flags are available. 2. **[Part 2 β€” JSON reference](#json-reference)** documents the structured output for scripts, CI pipelines and AI workflows β€” the JSON schema of every subcommand plus jq-based recipes. For the exhaustive option list see the auto-generated [CLI reference](cli.md#results). ## Quick start ```bash # Headline status of the latest run robotcode results summary # Headline status + the list of failing tests with their messages robotcode results summary --failed # Just the failing tests, sorted by who took longest robotcode results show --failed --sort elapsed # Full execution trace of every test that touches "Login" robotcode results log --search Login # Statistics grouped by tag (most failing tag first) robotcode results stats --by tag # What's broken now that wasn't broken before? robotcode results diff baseline/output.xml ``` If you never pass `--output`, the result file is **auto-discovered** from the active `robot.toml` profile β€” the same logic `robotcode robot` uses to decide where to write it. ## How the result file is located In order, `robotcode results` looks for: 1. An explicit `-o/--output PATH` argument. - If `PATH` is a regular file, it's used directly. - If `PATH` is a directory, the newest `output.xml` or `output.json` inside is picked. Useful when CI writes timestamped output directories. 2. The output file resolved from your active `robot.toml` profile (`output_dir` / `output` settings). 3. The most recent `output.xml` / `output.json` in the working directory. If none of those produce a file, the command exits with a clear error (`Result file not found …` or `No result file found in …`). If the file exists but cannot be parsed (corrupted XML, premature termination of the run), you get `failed to parse : …` with the underlying parser error. Both `output.xml` and `output.json` are supported; `robotcode results` picks the right parser automatically based on the file. (`output.json` is the RF 7.0+ opt-in format you get by passing `--output something.json` to `robotcode robot` or setting `output_format = "json"` in your profile.) ## Output formats The default TEXT output is meant for humans reading in a terminal β€” colourised, paginated, with timestamps. For pipelines, scripts and AI agents the global `-f/--format` flag β€” set **before** the subcommand β€” switches to a stable structured format: ```bash robotcode results summary # default: human-readable TEXT robotcode --format json results summary # compact JSON, one line robotcode --format json_indent results summary # pretty-printed JSON robotcode --format toml results summary # TOML ``` If you only ever look at terminal output, the following sections cover everything you need. For the JSON shape of any subcommand, jump to the [JSON reference](#json-reference). ### Pager and colour in the terminal When the TEXT output is longer than your terminal height, `robotcode` auto-pages it through the system pager β€” the program named in the `PAGER` environment variable, falling back to `less` on Unix and `more` on Windows. That spares you from scrolling a multi-screen `log` listing through your shell's scrollback. Quit the pager with `q`. Both colour and the pager auto-detect the situation: - **Interactive shell:** colour is on, and the pager kicks in once output exceeds the terminal height. - **Output redirected to a file or piped into another command:** both are off automatically; you get plain text on stdout. You can override the auto-detection explicitly with the global `--pager` / `--no-pager` and `--color` / `--no-color` flags: ```bash # Disable the pager β€” output streams directly to stdout robotcode --no-pager results log # Disable colour (the NO_COLOR=1 environment variable does the same) robotcode --no-color results show # Both at once β€” typical for CI logs robotcode --no-color --no-pager results summary ``` Use the positive forms (`--pager`, `--color`) to *force* either feature even when stdout isn't a TTY β€” handy when you want to pipe coloured output into `less -R` yourself. ## `summary` β€” headline numbers ```bash robotcode results summary ``` Output is a short block with the overall status, the test counts, the wall-clock time, and (with `--failed`) the list of failed tests above it. ```text Failures (2): FAIL MyProject.Login.Bad Password (tests/login/test_login.robot:42) AssertionError: Expected 'Login failed' but got 'Internal error' FAIL MyProject.Checkout.Empty Cart (tests/checkout/test_empty.robot:11) TimeoutError: keyword 'Open Cart' did not complete in 5s Summary: results/output.xml - Status: FAIL - Total: 42 - Passed: 37 - Failed: 2 - Skipped: 3 - Started: 2026-05-15 08:11:02 - Ended: 2026-05-15 08:12:25 - Elapsed: 1m 23s - Messages: 318 INFO, 7 WARN, 2 FAIL ``` ### Useful flags | Flag | Purpose | |---|---| | `--failed` | Append the list of failed tests, each with its message and source location | | `--full-paths` | Show absolute source paths instead of paths relative to the working directory | Filter flags (`--status`, `-i`, `-e`, `-s`, `-t`, `-bl`, `-ebl`) and `--search` work here too and narrow the underlying test set **before** the counts are computed. See [Filters](#filters) and [Search](#search). ## `show` β€” list individual tests `show` prints one row per test with status, source location, and (for failures) the truncated failure message. Use it to scan or to pull a specific subset. ```bash robotcode results show # all tests, execution order robotcode results show --top 10 # only the first 10 robotcode results show --failed # only failures (shorthand for --status fail) ``` ### Flag reference | Flag | Effect | |---|---| | `--sort name\|status\|elapsed\|start\|suite` | Reorder before output. Default: execution order from the output file. | | `--reverse` | Reverse whatever `--sort` produced. | | `--top N` | Keep only the first `N` after sorting. The dropped count is reported as a footer line. | | `--message-chars N` | Truncate failure messages to `N` characters (default `120`). Use `0` to disable truncation. | | `--tags` | Render the test's tags in the output, in normalised form (`Bug 1`, `bug_1` and `Bug1` all show as `bug1`). | | `--timing / --no-timing` | Show / hide start time and elapsed. Default: shown. | | `--full-paths` | Absolute source paths instead of relative. | ### Sort semantics Each `--sort` key has a *natural* direction β€” the one you almost always want. `--reverse` flips it. | Key | Natural order | |---|---| | `name` | Lexicographic, ascending, case-insensitive, on the full longname (`Suite.SubSuite.Test`) | | `suite` | Lexicographic, ascending, case-insensitive, on the parent-suite longname; tests within a suite keep their original order | | `status` | `FAIL` β†’ `SKIP` β†’ `PASS` β†’ `NOT RUN` (stable within a status group) | | `elapsed` | Longest first | | `start` | Earliest first | Tests with no value for the sort field (e.g. no recorded start time, no elapsed time) sort to the end regardless of `--reverse`. ### Recipes ```bash # What broke that's tagged smoke, sorted by who took longest? robotcode results show --include smoke --failed --sort elapsed # 10 slowest tests overall robotcode results show --sort elapsed --top 10 # Failing tests with full message (no truncation) and tags robotcode results show --failed --message-chars 0 --tags # Find tests by name match robotcode results show --search "TimeoutError" --tags # All tests of one specific suite, in name order robotcode results show --suite "MyProject.Login" --sort name ``` ## `log` β€” walk the execution tree `log` prints, for every selected test, the full execution body β€” keyword calls with arguments and assignments, control-flow blocks (FOR, WHILE, IF, TRY, …) with their children, iterations, individual log messages with their levels, and any artefacts (screenshots, embedded images, external file references) the run produced. ```bash robotcode results log # every test, every body item robotcode results log --failed # only failed tests (shorthand for --status fail) robotcode results log --search "Timeout" # only tests matching the search ``` ### Flag reference | Flag | Effect | |---|---| | `--level TRACE\|DEBUG\|INFO\|WARN\|ERROR\|FAIL` | Suppress messages below this severity. Default: `INFO`. | | `--max-depth N` | Collapse keyword bodies deeper than `N` levels. Default: `0` (unlimited). | | `--extract DIR` | Decode embedded `data:` URIs and copy externally-referenced files into `DIR`. | | `--raw-html` | Keep the original HTML markup in log messages. No artefact decoding happens in this mode. | | `--execution-messages` | Include parser/discovery errors that fired before the run (library import failures, syntax errors, …). | | `--keyword-info` | Print each executed keyword's `[Documentation]`, `[Tags]` and `[Timeout]` under its header (and add them to the JSON entry). Off by default; see [`--keyword-info` and `--suite-info`](#--keyword-info-and---suite-info). | | `--suite-info` | Group tests under suite headers showing the suite name, source, `Documentation` and `Metadata` (and add a `suites` array plus per-test `suite` ref to the JSON). Off by default. | | `--timestamps` | Show per-message timestamps. | | `--timing / --no-timing` | Show / hide start times and elapsed totals. | | `--full-paths` | Absolute source paths. | ### `--extract` directory layout `--extract DIR` creates `DIR` if needed, then writes one subdirectory per test: ``` DIR/ β”œβ”€β”€ MyProject.Login.Bad_Password/ β”‚ β”œβ”€β”€ embedded-0.png # first data:image/png base64 blob in the test β”‚ β”œβ”€β”€ embedded-1.png # second one β”‚ └── screenshot.png # external β”œβ”€β”€ MyProject.Checkout.Empty_Cart/ β”‚ └── ... ``` Test names are sanitised to filesystem-safe directory names (spaces become underscores, path separators are removed). External file references are resolved relative to the directory containing the result file; if the referenced file doesn't exist, the artefact is recorded as skipped with reason `missing-source` and nothing is copied. References that would escape the base directory via `..` are blocked β€” there is no way to overwrite files outside `DIR`. ### `--raw-html` vs default By default, log messages tagged as HTML (Robot Framework's `Log ... HTML`) are converted to a plain-text approximation: `` becomes a placeholder like `_(embedded image β€” see artefacts: no alt text)_` and the actual bytes are decoded and stored separately for `--extract`. `link` becomes a markdown-style link. With `--raw-html` the conversion is skipped β€” the original HTML markup is preserved verbatim and no artefacts are extracted. Use this when you want to feed the output into something that renders HTML itself. ### `--keyword-info` and `--suite-info` Both flags add **structured metadata** to the log output and are independent β€” you can pass either or both. They default to off so the standard `log` view stays compact. **`--keyword-info`** β€” for every executed `KEYWORD` / `SETUP` / `TEARDOWN`, the keyword's own `[Documentation]`, `[Tags]` and `[Timeout]` (taken from the keyword definition, not the call) are emitted. In TEXT the renderer prints them as indented `[Documentation] / [Tags] / [Timeout]` lines under the keyword header; in JSON they appear as `doc` / `tags` / `timeout` keys on the matching body-item entry. Fields whose underlying setting is empty are dropped, so `BuiltIn.Log` (which has a docstring but no tags) shows only `doc`. **`--suite-info`** β€” tests get grouped under one `Suite:` header per parent suite. The header carries the suite's `fullName`, source path, executed status, plus the suite's `Documentation` (with `...` continuation lines for multi-line docs) and one `[Metadata]` line per key. In JSON, `LogResult.suites` is populated with one entry per surviving suite, and every test gains a `suite` field cross-referencing the parent suite by `fullName`. Combine both for a maximal view that mirrors the structure of the original `.robot` files: ```bash robotcode results log --suite-info --keyword-info ``` Example TEXT output: ``` Suite: MyProject.Login (tests/login.robot) PASS [Documentation] Exercises the login flow against the staging environment. [Metadata] OwnerTeam = identity-squad Test: MyProject.Login.Bad Password (tests/login.robot:42) FAIL [SETUP] Open Browser PASS [Documentation] Launches a fresh Chromium with our shared profile. [Tags] browser setup ... ``` ### Recipes ```bash # Drill into one failing test robotcode results log -bl MyProject.Login.Bad_Password # Walk only the FAIL-level messages of every failed test robotcode results log --failed --level FAIL # Top-level keyword calls only, with everything nested collapsed robotcode results log --max-depth 1 # Pull screenshots out of a failed run robotcode results log --failed --extract ./extracted # Diagnose suites that broke before they even ran robotcode results log --execution-messages --level WARN # Full structured view β€” suite headers + per-keyword doc/tags/timeout robotcode results log --suite-info --keyword-info ``` ## `stats` β€” aggregate by tag, suite, or status `stats` answers questions like "which tag has the worst pass rate" or "which suite is consuming most of my CI time". You pick one or more aggregation dimensions and `stats` emits one table per dimension. ```bash robotcode results stats # default: by status robotcode results stats --by tag robotcode results stats --by suite robotcode results stats --by tag --by suite # two sections, in the requested order ``` Output: ```text By Tag: NAME TOTAL PASS FAIL SKIP ELAPSED regression 24 19 5 0 4m 12s smoke 18 18 0 0 47s slow 7 5 1 1 2m 03s bug-1842 2 0 2 0 8s By Suite: NAME TOTAL PASS FAIL SKIP ELAPSED MyProject.Checkout 14 10 4 0 3m 11s MyProject.Login 12 12 0 0 1m 02s MyProject.Search 8 7 0 1 52s ``` ### Flag reference | Flag | Effect | |---|---| | `--by tag\|suite\|status` | Aggregation dimension. Repeatable for multiple sections. Default: `--by status`. | | `--sort name\|total\|failed\|elapsed` | Order groups within each section. Default: `failed` descending β€” most painful first. | | `--top N` | Keep at most `N` groups per section. The dropped count is reported as a footer line. | ### Aggregation rules - **`--by tag`**: a test with N tags counts in N buckets. Tags that differ only in case, whitespace or underscores (`Bug 1`, `bug_1`, `Bug1`) are treated as the same tag and merge into one bucket, displayed in normalised form. Tests without tags drop out β€” there is **no** "(untagged)" bucket. The elapsed time per group is the **sum** across all matching tests (not the average). - **`--by suite`**: groups are keyed by the test's parent suite **full longname**, not the leaf name. `MyProject.Login` and `MyProject.Checkout.Login` are distinct groups. - **`--by status`**: groups are the literal status strings `PASS`, `FAIL`, `SKIP`, `NOT RUN`. Empty buckets are omitted. Filters and `--search` are applied **before** aggregation. That makes questions like "for the smoke subset, which suite has the most failures?" a single command: ```bash robotcode results stats --include smoke --by suite --sort failed ``` ### Recipes ```bash # Worst tags by failure count (default sort) robotcode results stats --by tag # Five worst tags only robotcode results stats --by tag --top 5 # Where is the CI time going? robotcode results stats --by suite --sort elapsed # Status breakdown for one specific tag robotcode results stats --include flaky --by status ``` ## `diff` β€” compare two runs `diff` matches tests across two result files by **full longname** and classifies the differences. Use it for regression triage, to spot flaky tests, or to confirm that a fix has actually landed. ```bash robotcode results diff baseline/output.xml # current is auto-discovered robotcode results diff baseline/output.xml current/output.xml # explicit pair ``` ### Output sections | Section | Tests that … | |---|---| | `new failures` | passed in baseline, fail in current β€” regressions | | `new passes` | failed or skipped in baseline, pass in current β€” fixes | | `status changes` | otherwise changed status (e.g. `SKIP β†’ FAIL`, `FAIL β†’ SKIP`) | | `added` | exist only in current (added since baseline) | | `removed` | exist only in baseline (deleted/renamed since baseline) | Tests that have the same status in both runs are **not** reported β€” `diff` shows changes only. ### Flag reference | Flag | Effect | |---|---| | `--only new-failures\|new-passes\|status-changes\|added\|removed` | Restrict output to these categories. Repeatable. | | `--message-chars N` | Truncate the per-entry messages to `N` chars. Default: `120`. | | `--full-paths` | Absolute source paths. | The standard `--status / -i / -e / -s / -t / -bl / -ebl / --search / --search-regex` filters apply to **both** baseline and current before matching. This lets you scope the comparison to a tag, sub-suite, or pattern without re-running anything: ```bash robotcode results diff baseline.xml --include smoke robotcode results diff baseline.xml --suite "*.Checkout.*" robotcode results diff baseline.xml --search Timeout ``` ### Why `diff` always exits 0 `diff` exits 0 even when there are new failures, so it composes cleanly with other tools. For a regression gate, drive the exit code from the structured output β€” see [CI recipes](#ci-recipes) in the JSON reference. ### When tests have been renamed `diff` matches on `fullName`. A rename therefore looks like one `removed` entry plus one `added` entry β€” even if the test bodies are identical. There is currently no fuzzy-match mode; if rename detection is important to you, keep test names stable or post-process the JSON. ### Recipes ```bash # Regression triage: every new failure, full message, with sources robotcode results diff baseline.xml --only new-failures --message-chars 0 --full-paths # Diff only the smoke subset robotcode results diff baseline.xml --include smoke # Compare two CI runs (e.g. main vs feature branch) robotcode results diff main/output.xml branch/output.xml ``` ## Filters Every subcommand accepts the same filter set. Filters combine with **AND** β€” every test must satisfy every filter to make it through. Within a single repeatable flag (`--status`, `--include`, etc.) the matches combine with **OR** in the way Robot Framework normally treats those options. | Flag | Behavior | |---|---| | `--status pass\|fail\|skip\|not-run` | Repeatable; tests whose status is in the chosen set. | | `--failed` / `--passed` / `--skipped` | Shorthands for `--status fail` / `--status pass` / `--status skip`. Additive with `--status` and with each other (OR semantics). Available on `show`, `log`, `stats`. | | `-i/--include TAG_PATTERN` | Robot tag-pattern syntax (see below). Repeatable. | | `-e/--exclude TAG_PATTERN` | Same syntax, exclusion side. Repeatable. | | `-s/--suite GLOB` | Match against the suite's full longname. Repeatable. | | `-t/--test GLOB` | Match against the test's full longname. Aliased as `--task`. Repeatable. | | `-bl/--by-longname NAME` | Exact longname match (no glob expansion). Repeatable. | | `-ebl/--exclude-by-longname NAME` | Exclusion variant of `--by-longname`. Repeatable. | ### Tag-pattern syntax (`-i`/`-e`) Tag patterns follow Robot Framework's own rules: - A plain tag (`smoke`) matches tests carrying that tag. - `AND` (uppercase) requires multiple tags: `smokeANDregression` matches only tests that have **both** tags. - `NOT` excludes: `smokeNOTslow` matches `smoke` minus `slow`. - Tags are matched case-insensitively, and whitespace and underscores are ignored β€” `smoke_test`, `Smoke Test` and `smoketest` all refer to the same tag. Other punctuation, including hyphens, is significant: `bug-123` and `bug123` are distinct. - Glob characters `*` and `?` work inside a tag pattern: `bug-*` matches any tag starting with `bug-`. You can repeat `-i` to OR multiple patterns: `-i smoke -i regression` selects tests that carry **either** `smoke` **or** `regression`. ### Suite / test globs `-s` / `-t` accept shell-style glob patterns matched against the full longname: - `*` matches any sequence of characters (including `.`, so `*.Login.*` matches at any depth). - `?` matches a single character. - Matching is case-insensitive and applied to the full longname (`MyProject.Login.Bad Password`). - Repeat for OR: `-s "MyProject.Login.*" -s "MyProject.Checkout.*"`. Quote globs in the shell β€” `--suite "*.Login.*"` and `--test "Test ?"` need quotes so the shell doesn't expand them against the local filesystem. ### `--by-longname` vs `--suite` / `--test` - `-s` / `-t` are **glob** matches and accept patterns. - `-bl` / `-ebl` are **exact** matches against the full longname β€” no glob expansion. They mirror `robotcode robot --by-longname` so you can hand the same names to `robot` and `results`. Use `-bl` when you have a precise name to filter against (often pasted from the failure list); use `-s/-t` when you want pattern matching. ## Search `--search` and `--search-regex` are **mutually exclusive** (passing both is a usage error). They apply across: - the test's `name` and full longname - the test's failure message - the test's tags - the test's `[Documentation]`, `[Template]` and `[Timeout]` - every keyword call's name, arguments and assignments within the test body - every executed keyword's `[Documentation]`, `[Tags]` and `[Timeout]` (taken from the keyword definition; result-tree only) - every log message's text - any **ancestor suite**'s `Documentation` or `Metadata` (a hit on a suite-level field keeps every test underneath it) A test matches if **any** of those targets matches. Once `log` decides a test matches, all of its body items are emitted as usual β€” the search is a test-level filter, not a per-message filter. | Flag | Semantics | |---|---| | `--search TEXT` | Case-insensitive substring match. No metacharacters; `[` and `*` are literal. | | `--search-regex PATTERN` | Regular expression, **case-sensitive** by default. Use `(?i)` at the start of the pattern for case-insensitive matching. | When matching against **tags** specifically, both the pattern and each tag are normalised the way Robot Framework normalises tags (lowercase, whitespace and underscores ignored). So `--search "bug 1"` matches tests tagged `bug_1`, `Bug1`, or `BUG 1`. Other targets β€” name, message, keyword arguments, log text β€” are matched literally without normalisation. ```bash robotcode results log --search "TimeoutError" robotcode results log --search-regex 'AssertionError.*expected: \d+' robotcode results log --search-regex '(?i)login' # case-insensitive ``` ### Anchors and alternation The regex is matched against each target string individually, **not anchored** to the whole string β€” a pattern like `Login` matches any target that contains `Login` somewhere. Use `^` and `$` if you want anchored matches. Note that anchors apply per target string, so `^Login` matches a test whose full longname is `Login.Bad Password` but also a keyword named `Login With Token` somewhere inside the test body. ### Highlighting in the terminal On `log` (and `show`), matches are highlighted inline in the TEXT output with a yellow background so you can scan visually. Structured output (JSON/TOML) is unchanged β€” searching only filters, it doesn't add markup. ### Search on `summary` and `stats` `--search` works on these too, but its effect is subtle: the matching tests narrow the input set, and the counts / aggregations are computed against that narrowed set. So `robotcode results summary --search Login` is "how is the Login subset doing" and `robotcode results stats --by tag --search Login` is "which tags are involved in the Login subset". ### Invalid patterns An unparseable regex (e.g. `[unclosed`) yields a usage error pinpointing where the pattern failed to compile. The command exits non-zero before reading the result file. ## Tips for terminal use - **TEXT output is markdown.** On a coloured TTY the markdown is rendered to themed ANSI via `rich` (and paged if longer than your terminal); on pipes or with `--no-color` the raw markdown goes through verbatim β€” paste it into a PR description, a Slack message, or feed it straight to an LLM. - **Quote your globs.** `--suite "*.Login.*"` and `--test "Test ?"` need quotes so the shell doesn't expand them against the local filesystem first. - **Filters apply before aggregation.** `stats`, `summary` and `diff` all run the filter pipeline first, so `--search Login` followed by `--by tag` gives you tag stats over the Login subset, not all tags whose name happens to contain "Login". - **`-bl` is for exact names, `-t` is for patterns.** When you copy a failing-test name out of the failure list, `-bl` is usually what you want β€” no need to escape glob characters. - **Save your baselines.** Archive `output.xml` from your green main branch (or main-CI run) and feed it to `diff` from feature branches β€” that's the fastest way to catch regressions before review. - **`diff` doesn't fail the build.** It always exits 0. If you want a regression gate, see the [CI recipes](#ci-recipes) in the JSON reference. --- # JSON reference When you set `-f json` (or `-f json_indent` for pretty-printed, or `-f toml`) between `robotcode` and the subcommand, every result command emits structured data instead of the terminal-formatted text. This is what CI pipelines, scripts and AI agents consume. ```bash robotcode --format json results summary robotcode --format json results show --failed --sort elapsed robotcode --format json results log --failed ``` This part of the guide is the schema reference: what fields each subcommand emits, when they're present, and how to consume them safely. ## Schema rules A few rules hold across every subcommand: - **camelCase keys.** `fullName`, `elapsedSeconds`, `messagesCount`, etc. - **ISO-8601 timestamps** with microsecond resolution. - **Optional fields are omitted, not `null`.** A `null` literal never appears in the output. If a field has no value (e.g. `failed` without `--failed`, `tags` on an untagged test), the key is simply absent from the JSON object. - **Scalar fields with a meaningful zero are always emitted.** `counts.failed = 0`, `truncated = 0`, `elapsedSeconds = 0.0` all stay in the object. Only optional fields disappear when unset. - **Empty array β‰  missing field.** Sections that "exist but are empty" come through as `[]`; sections that were never requested (e.g. anything excluded by `diff --only`) are absent. The two are different and your queries should handle both, typically via `// []` in jq. - **Stability.** Fields are appended over time, never renamed or removed in place. New fields are additive; existing consumers keep working. ## `summary` JSON ```json { "file": { "source": "results/output.xml", "relSource": "results/output.xml" }, "status": "FAIL", "counts": { "total": 42, "passed": 37, "failed": 2, "skipped": 3, "notRun": 0 }, "elapsedSeconds": 83.4, "startTime": "2026-05-15T08:11:02", "endTime": "2026-05-15T08:12:25", "failed": [ { "name": "Bad Password", "fullName": "MyProject.Login.Bad Password", "suite": "MyProject.Login", "status": "FAIL", "message": "AssertionError: Expected 'Login failed' but got 'Internal error'", "tags": ["smoke"], "elapsedSeconds": 0.234, "startTime": "2026-05-15T08:11:04", "source": "tests/login/test_login.robot", "relSource": "tests/login/test_login.robot", "lineno": 42 } ], "messagesCount": { "INFO": 318, "WARN": 7, "FAIL": 2 } } ``` Field notes: - `failed` only appears when `--failed` was passed. - `messagesCount` aggregates log messages by level (`TRACE` / `DEBUG` / `INFO` / `WARN` / `ERROR` / `FAIL`). Only levels with at least one message appear β€” empty buckets are omitted, not emitted as `0`. - `executionMessagesCount` (parser / discovery errors that fired outside of test execution) appears **only** when there were any. - `filtersApplied` (see [below](#filtersapplied)) appears when any filter was passed. ## `show` JSON ```json { "file": { "source": "results/output.xml" }, "counts": { "total": 42, "passed": 37, "failed": 2, "skipped": 3, "notRun": 0 }, "tests": [ { "name": "Bad Password", "fullName": "MyProject.Login.Bad Password", "suite": "MyProject.Login", "status": "FAIL", "message": "AssertionError: Expected 'Login failed' …", "tags": ["smoke", "regression"], "elapsedSeconds": 0.234, "startTime": "2026-05-15T08:11:04", "source": "tests/login/test_login.robot", "lineno": 42 } ], "truncated": 0, "elapsedSeconds": 83.4, "startTime": "2026-05-15T08:11:02", "endTime": "2026-05-15T08:12:25" } ``` Field notes: - `tests[]` is always present, possibly empty. - `tags` is always emitted for tests that have any (and absent for untagged tests), in normalised form (`Bug 1`, `bug_1`, `Bug1` all come through as `"bug1"`). The `--tags` flag in TEXT mode is render-only β€” it doesn't affect the JSON. - `truncated` is the number of tests dropped by `--top N`; `0` when nothing was dropped. - The order of `tests[]` reflects `--sort` and `--reverse`. ## `log` JSON ```json { "file": { "source": "results/output.xml" }, "tests": [ { "fullName": "MyProject.Login.Bad Password", "status": "FAIL", "message": "AssertionError: Expected 'Login failed' …", "body": [ /* recursive tree of body items, see below */ ], "artifacts": [ /* aggregated artifact refs for the whole test */ ], "source": "tests/login/test_login.robot", "lineno": 42, "elapsedSeconds": 0.234, "startTime": "2026-05-15T08:11:04", "suite": "MyProject.Login" } ], "suites": [ { "fullName": "MyProject.Login", "name": "Login", "status": "FAIL", "doc": "Exercises the login flow against staging.", "metadata": { "OwnerTeam": "identity-squad" }, "source": "tests/login.robot", "elapsedSeconds": 12.7, "startTime": "2026-05-15T08:11:02" } ], "executionMessages": [ /* only with --execution-messages */ ], "extractDir": "./extracted", "extractedCount": 7 } ``` The `body` array of each test is a recursive tree of body items. Field notes: - `extractDir` / `extractedCount` appear only with `--extract DIR`. - `executionMessages` appears only with `--execution-messages`. - `suites` and the per-test `suite` cross-reference appear only with `--suite-info`. One `suites` entry per parent suite that has at least one surviving test, in traversal order. Empty `metadata` / `doc` are dropped. - Artefact entries carry `kind` (`"image"` | `"file"`), `src`, and β€” when extraction happened β€” `extractedTo` (absolute path of the written file). Failed extractions get a `skippedReason` instead (e.g. `"missing-source"`, `"target-traversal"`). ### Body-item types Every body-item entry has a `type` field. The vocabulary tracks Robot Framework's own body-item taxonomy: | `type` | What it represents | Notable fields | |---|---|---| | `KEYWORD` | A keyword call | `name`, `owner`, `args`, `assign`, `body` | | `SETUP` / `TEARDOWN` | Suite/test setup or teardown keyword | same as `KEYWORD` | | `FOR` | `FOR` loop | `flavor` (`IN`/`IN RANGE`/`IN ENUMERATE`/`IN ZIP`), `body` (iterations) | | `ITERATION` | One iteration of a `FOR` / `WHILE` loop | `assign` (the loop variable values), `body` | | `WHILE` | `WHILE` loop | `condition`, `body` | | `IF` / `ELSE IF` / `ELSE` | Conditional branches | `condition` (on `IF` / `ELSE IF`), `body` | | `TRY` / `EXCEPT` / `FINALLY` | Exception handling | `patterns`, `patternType` (on `EXCEPT`) | | `VAR` | `VAR` assignment statement | `assign` (variable name), `args` (value), `scope` | | `RETURN` / `BREAK` / `CONTINUE` | Control-flow exits | `args` (values for `RETURN`) | | `GROUP` | `GROUP` block | `name`, `body` | | `ERROR` | Recorded execution error | `args` | | `MESSAGE` | A log message | `level`, `text`, `timestamp`, `isHtml`, `artifacts` | Every entry carries `status`, `elapsedSeconds` and `startTime` where applicable. The recursive `body` field is what makes the tree walkable β€” you can drill into a `FOR` loop's `ITERATION` and then into the `KEYWORD` calls inside each iteration. With **`--keyword-info`**, every `KEYWORD` / `SETUP` / `TEARDOWN` entry additionally carries the keyword's own definition metadata: | Field | When it appears | |---|---| | `doc` | Keyword has a `[Documentation]` setting (library keywords always do; user keywords only when written). | | `tags` | Keyword has at least one `[Tags]` entry. | | `timeout` | Keyword has a `[Timeout]` setting. | Empty entries are dropped β€” a user keyword without `[Tags]` will not have a `tags` key. ## `stats` JSON ```json { "file": { "source": "results/output.xml" }, "sections": [ { "dimension": "tag", "groups": [ { "name": "regression", "counts": { "total": 24, "passed": 19, "failed": 5, "skipped": 0, "notRun": 0 }, "elapsedSeconds": 252.1 } ], "truncated": 0 } ] } ``` Field notes: - `sections[]` has one entry per `--by` dimension, in the order they appeared on the command line. - `dimension` is `"tag"` | `"suite"` | `"status"`. - `groups[]` is sorted by `--sort` (default: `failed` descending) and capped by `--top N`. - `elapsedSeconds` per group is the **sum** of test elapsed times in that group. - `truncated` is the number of groups dropped by `--top N`. ## `diff` JSON ```json { "baseline": { "source": "baseline/output.xml" }, "current": { "source": "current/output.xml" }, "newFailures": [ { "fullName": "MyProject.Login.Bad Password", "baselineStatus": "PASS", "currentStatus": "FAIL", "currentMessage": "AssertionError: Expected 'Login failed' …", "source": "tests/login/test_login.robot", "relSource": "tests/login/test_login.robot", "lineno": 42 } ], "newPasses": [], "statusChanges": [], "added": [], "removed": [] } ``` Field notes: - Without `--only`, all five section arrays (`newFailures`, `newPasses`, `statusChanges`, `added`, `removed`) are always present β€” empty `[]` when nothing matched. - With `--only`, sections you didn't list are **omitted entirely** from the JSON. Use `// []` in jq when accessing fields that may be missing. - Each entry carries `fullName`, the relevant status fields, and (when they exist) the relevant messages. `baselineMessage` / `currentMessage` are omitted when the corresponding run had no failure message. ## `filtersApplied` Every subcommand's JSON output includes a `filtersApplied` field when **any** filter was passed. It echoes back the filters the command actually saw: ```json "filtersApplied": { "status": ["fail"], "include": ["bug1"], "exclude": ["smokeANDregression"], "suite": ["*.Login.*"] } ``` Most filters come back verbatim. The two exceptions are `include` and `exclude`: - A plain single-tag pattern is normalised the way Robot would (`BUG 1` β†’ `bug1`, `Smoke_Test` β†’ `smoketest`), so you see how the filter is actually being compared. - A pattern containing an uppercase `AND` / `OR` / `NOT` operator is echoed verbatim, because each operand would need to be normalised individually and the surrounding structure carries deliberate meaning. This is useful when piecing together a complex CI command β€” you can assert that the filter set ended up where you expected. When no filters were passed, the field is absent. ## CI recipes A grab-bag of jq-based recipes. Pin `-f json` between `robotcode` and the subcommand to lock the format. ### Pass/fail the build ```bash # Fail on any test failure robotcode --format json results summary | jq -e '.counts.failed == 0' # Fail only on new failures vs a checked-in baseline robotcode --format json results diff baseline/output.xml \ | jq -e '(.newFailures // []) | length == 0' # Allow a fixed budget of failures FAILED=$(robotcode --format json results summary | jq '.counts.failed') test "$FAILED" -le 3 ``` ### Slow-test report ```bash # Top 20 slowest tests, CSV robotcode --format json results show --sort elapsed --top 20 \ | jq -r '.tests[] | [.fullName, .elapsedSeconds] | @csv' # Tag-level elapsed budget (minutes) robotcode --format json results stats --by tag --sort elapsed \ | jq -r '.sections[].groups[] | [.name, (.elapsedSeconds / 60)] | @csv' ``` ### Notification payloads ```bash # One-line Slack-style message robotcode --format json results summary \ | jq -r '"\(.status): \(.counts.passed)/\(.counts.total) passed in \(.elapsedSeconds / 60 | floor)m. \(.counts.failed) failed."' # Diff summary against main robotcode --format json results diff baseline.xml \ | jq -r '"+ \((.added // []) | length) added Β· - \((.removed // []) | length) removed Β· \((.newFailures // []) | length) regressions Β· \((.newPasses // []) | length) fixes"' ``` ### Artefact gathering ```bash # After a failed CI run: pull screenshots out for upload robotcode results log --failed --extract ./extracted # Then: zip the lot zip -r artefacts.zip ./extracted ``` ### Flakiness signal ```bash # Tests that flipped state between two runs (either direction) robotcode --format json results diff run-1.xml run-2.xml \ | jq '((.newFailures // []) + (.newPasses // [])) | map(.fullName)' ``` ## Tips for scripting - **Pin the output format.** Always say `-f json` (between `robotcode` and the subcommand). The TEXT format is meant for humans and may evolve. - **Empty array β‰  missing field.** Sections that exist but are empty come through as `[]`. Sections excluded by `diff --only` are absent. Use `// []` in jq to handle both. - **Optional fields are absent, never `null`.** Test for presence of the key rather than for a `null` value; in jq use `(.failed // empty)`. - **Trust `filtersApplied`.** If you're not sure your filters are being honoured, the field echoes them back β€” tag patterns in their canonical (normalised) form, everything else verbatim. - **For AI agents:** when feeding tool output into an LLM, prefer the narrowest subcommand call you can make (`summary` over `show`, `show --top 5` over a full listing, `log --failed --level FAIL` over an unfiltered log). Each layer of filtering saves tokens and reduces the amount of reasoning the model has to spend on parsing. --- URL: "/03_reference/cli" LLMS_URL: "/03_reference/cli.md" --- # Command Line Interface (CLI) The `robotcode` CLI tool enables seamless interaction with Robot Framework through the command line, offering a comprehensive set of features for project analysis, debugging, and configuration management. The CLI tool is designed to be straightforward and user-friendly, with a broad range of commands to support various use cases, including test execution, documentation generation, and code analysis. It also supports configuration profiles, allowing users to define and quickly switch between different project setups as needed. In most cases, not all CLI components are required within a single project. For example, in a CI (Continuous Integration) environment, only the `runner` package is typically necessary to execute tests, while the `language-server` package is generally not needed. The `analyze` package is mainly useful in a development environment to detect syntax errors and validate code, but it may be unnecessary in production or deployment environments. Similarly, the `debugger` package is essential for local development when troubleshooting test cases but isn’t usually required in production or CI pipelines. To accommodate these varied needs, `robotcode` is organized into separate packages that each focus on specific functions. The core package, `robotcode`, provides foundational support for working with `robot.toml` configuration files and profile management. Here’s a more detailed breakdown of each package and its capabilities: - **`robotcode` Core Package**: Always installed, the core package provides the top-level `robotcode` command together with the global options (config files, profiles, output format, paging, …) shared by every other command. It also includes commands to inspect the resolved configuration and the profiles defined for a project. - **Commands**: - `config`: Shows the merged `robot.toml` configuration and which files contributed to it, making it easy to understand how settings are resolved. - `profiles`: Lists the profiles defined for the project and shows their resulting configuration, helping verify which profile applies in a given context. - **`runner` Package**: This package is essential for users who need to run and manage tests within Robot Framework projects. It includes commands for executing tests, generating documentation, and discovering test elements. This package is especially important in CI/CD pipelines, where automation of test execution is a primary focus. - **Commands**: - `robot`, `rebot`, `libdoc`, `testdoc`: Enhanced versions of the standard Robot Framework tools, with support for `robot.toml` configuration files and profiles, allowing customized setups for different environments or testing requirements. - `discover`: Searches the project for tests, suites, tags, tasks, and other elements, providing a quick overview of available test cases and project structure. - `results`: Inspects a finished run's `output.xml`/`output.json` β€” summaries, failures, the per-test execution log, and diffs between two runs β€” without re-executing the tests. - **`analyze` Package**: This package provides tools for detailed inspection and validation of Robot Framework code, helping users identify errors and improve code quality. The `analyze` package is typically more useful in development environments where code quality checks and error detection are needed before moving tests to a CI or production environment. - **Commands**: - `analyze`: Analyzes Robot Framework scripts for syntax errors, undefined keywords, and other potential issues, allowing early detection of problems and ensuring adherence to best practices. - **`debugger` Package**: The debugger package enables powerful debugging capabilities for Robot Framework tests by providing a Debug Adapter Protocol (DAP)-compatible debugger. This package is most beneficial in development or local testing environments where developers need to diagnose and troubleshoot test issues. A DAP client, such as Visual Studio Code, can be connected to initiate and control debug sessions, enabling features like setting breakpoints, stepping through code, and inspecting variables. - **Commands**: - `debug`: Starts a DAP-compatible debug session for Robot Framework tests. This tool requires a DAP client to connect to the debug session, such as Visual Studio Code, which can then interface with the debugger and provide interactive debugging tools to analyze code behavior and troubleshoot issues effectively. - **`repl` Package**: The REPL (Read-Eval-Print Loop) package provides an interactive, real-time environment for executing Robot Framework commands. It’s ideal for experimenting with keywords, testing ideas, and performing quick debugging without needing to create full test files. It also ships a command-line debugger for Robot Framework runs. This package is mainly used in local development or testing environments where users can quickly prototype or troubleshoot commands. - **Commands**: - `repl`: Launches an interactive Robot Framework shell where users can execute commands line-by-line, ideal for quick testing and experimentation. - `robot-debug`: Runs a real `.robot` suite with the command-line debugger attached, pausing at breakpoints to step through execution, inspect the call stack and variables, and run keywords in the paused context. - **`language-server` Package**: This package provides language server capabilities, supporting IDE integration for Robot Framework with real-time code insights. Compatible with editors that support the Language Server Protocol (LSP), such as Visual Studio Code, it enables enhanced productivity and convenience. It is most useful in local development environments where interactive IDE support aids in code writing and refactoring but is generally not needed in CI or production environments. - **Commands**: - `language-server`: Starts the RobotCode Language Server, which provides features like syntax highlighting, auto-completion, and code analysis, designed to improve the Robot Framework development experience within IDEs. ## Installation To install the core `robotcode` CLI tool, use `pip`: ```bash pip install robotcode ``` This command installs only the main package. For specific functionality, additional packages can be installed as needed: ```bash pip install robotcode[runner] pip install robotcode[analyze] pip install robotcode[debugger] pip install robotcode[repl] pip install robotcode[languageserver] ``` To install all packages, including optional dependencies, use: ```bash pip install robotcode[all] ``` This includes additional tools, such as [`robocop`](https://robocop.readthedocs.io) for linting and formatting, which further enhance the development experience with Robot Framework. ## Commands The following sections outline all available commands, their usage, and the corresponding options. Options with and asterisk (*) can be specified multiple times. ### robotcode A CLI tool for Robot Framework. **Usage:** ```text robotcode [OPTIONS] COMMAND [ARGS]... ``` **Options:** - `-c, --config PATH *` Config file to use. If not specified, the default config file is used. [env var: ROBOTCODE_CONFIG_FILES] - `-p, --profile TEXT *` The Execution Profile to use. If not specified, the default profile is used. [env var: ROBOTCODE_PROFILES] - `-r, --root DIRECTORY` Specifies the root path to be used for the project. It will be automatically detected if not provided. [env var: ROBOTCODE_ROOT] - `--no-vcs` Ignore version control system directories (e.g., .git, .hg) when detecting the project root. [env var: ROBOTCODE_NO_VCS] - `-f, --format [toml|json|json_indent|text]` Set the output format. - `-d, --dry` Dry run, do not execute any commands. [env var: ROBOTCODE_DRY] - `--color / --no-color` Force or disable colored output. Default (no flag): auto-detect β€” colors only when stdout is a TTY, disabled if `NO_COLOR` is set, forced if `FORCE_COLOR` is set. [env var: ROBOTCODE_COLOR] - `--pager / --no-pager` Force or disable the pager. Default (no flag): auto-page when the rendered output exceeds the terminal height. [env var: ROBOTCODE_PAGER] - `-v, --verbose` Enables verbose mode. [env var: ROBOTCODE_VERBOSE] - `--log` Enables logging. [env var: ROBOTCODE_LOG] - `--log-level [TRACE|DEBUG|INFO|WARNING|ERROR|CRITICAL]` Sets the log level. [env var: ROBOTCODE_LOG_LEVEL; default: CRITICAL] - `--log-format TEXT` Sets the log format. See python logging documentation for more information. [env var: ROBOTCODE_LOG_FORMAT; default: %(levelname)s:%(name)s:%(message)s] - `--log-style [%|{|$]` Sets the log style. See python logging documentation for more information. [env var: ROBOTCODE_LOG_STYLE; default: %] - `--log-filename FILE` Write log output to a file instead to console. [env var: ROBOTCODE_LOG_FILENAME] - `--log-calls` Enables logging of method/function calls. [env var: ROBOTCODE_LOG_CALLS] - `--log-config FILE` Path to a logging configuration file. This must be a valid Python logging configuration file in JSON format. If this option is set, the other logging options are ignored. [env var: ROBOTCODE_LOG_CONFIG] - `--version` Show the version and exit. - `--help` Show this message and exit. **Commands:** - [`analyze`](#analyze) The analyze command provides various subcommands for analyzing Robot Framework code. - [`config`](#config) Shows information about the configuration. - [`debug`](#debug) Starts a Robot Framework debug session and waits for incomming connections. - [`debug-launch`](#debug-launch) Launches a robotcode debug session. - [`discover`](#discover) Commands to discover informations about the current project. - [`language-server`](#language-server) Run Robot Framework Language Server. - [`libdoc`](#libdoc) Runs `libdoc` with the selected configuration, profiles, options and arguments. - [`profiles`](#profiles) Shows information on defined profiles. - [`rebot`](#rebot) Runs `rebot` with the selected configuration, profiles, options and arguments. - [`repl`](#repl) Run Robot Framework interactively (alias `shell`). - [`repl-server`](#repl-server) Start a REPL server, client can connect to the server and run the REPL scripts. - [`results`](#results) Inspect a finished run's `output.xml` / `output.json` β€” counts, failures, and per-test execution tree, without re-running. - [`robot`](#robot) Runs `robot` with the selected configuration, profiles, options and arguments. - [`robot-debug`](#robot-debug) Run a real Robot Framework suite with the debugger attached (alias `run-debug`). - [`testdoc`](#testdoc) Runs `testdoc` with the selected configuration, profiles, options and arguments. **Aliases:** - [`shell`](#repl) Run Robot Framework interactively (alias `shell`). - [`run`](#robot) Runs `robot` with the selected configuration, profiles, options and arguments. - [`run-debug`](#robot-debug) Run a real Robot Framework suite with the debugger attached (alias `run-debug`). #### analyze The analyze command provides various subcommands for analyzing Robot Framework code. These subcommands support specialized tasks, such as code analysis, style checking or dependency graphs. **Usage:** ```text robotcode analyze [OPTIONS] COMMAND [ARGS]... ``` **Options:** - `--version` Show the version and exit. - `--help` Show this message and exit. **Commands:** - [`cache`](#cache) Manage the RobotCode analysis cache. - [`code`](#code) Performs static code analysis to identify potential issues in the specified *PATHS*. ##### cache Manage the RobotCode analysis cache. Provides subcommands to inspect, list, and clear cached data (library docs, variables, resources, namespaces). **Usage:** ```text robotcode analyze cache [OPTIONS] COMMAND [ARGS]... ``` **Options:** - `--help` Show this message and exit. **Commands:** - [`clear`](#clear) Clear the analysis cache. - [`info`](#info) Show cache statistics. - [`list`](#list) List cached entries. - [`path`](#path) Print the cache directory path. - [`prune`](#prune) Remove the entire cache directory. ###### clear Clear the analysis cache. Removes cached entries from the database. By default clears all sections. Use --section to clear specific sections only. **Usage:** ```text robotcode analyze cache clear [OPTIONS] [PATHS]... ``` **Options:** - `-s, --section SECTION *` Clear only specific sections (library, variables, resource, namespace). Can be specified multiple times. - `--help` Show this message and exit. ###### info Show cache statistics. Displays the cache directory, database size, app version, and per-section entry counts with timestamps. **Usage:** ```text robotcode analyze cache info [OPTIONS] [PATHS]... ``` **Options:** - `--help` Show this message and exit. ###### list List cached entries. Shows all entries in the cache with their timestamps and sizes. Use --section to filter by specific cache sections. Use --pattern to filter entries by glob pattern. **Usage:** ```text robotcode analyze cache list [OPTIONS] [PATHS]... ``` **Options:** - `-s, --section SECTION *` Filter by section (library, variables, resource, namespace). Can be specified multiple times. - `-p, --pattern PATTERN *` Filter entries by glob pattern (e.g. 'robot.*', '*BuiltIn*'). Can be specified multiple times. - `--help` Show this message and exit. ###### path Print the cache directory path. Outputs the resolved cache directory for the current project and Python/Robot Framework version combination. **Usage:** ```text robotcode analyze cache path [OPTIONS] [PATHS]... ``` **Options:** - `--help` Show this message and exit. ###### prune Remove the entire cache directory. Deletes the .robotcode_cache directory and all its contents, including caches for all Python and Robot Framework versions. **Usage:** ```text robotcode analyze cache prune [OPTIONS] [PATHS]... ``` **Options:** - `--force` Force prune even if cache is in use by another process. - `--help` Show this message and exit. ##### code Performs static code analysis to identify potential issues in the specified *PATHS*. The analysis detects syntax errors, missing keywords or variables, missing arguments, and other problems. - **PATHS**: Can be individual files or directories. If no *PATHS* are provided, the current directory is analyzed by default. The return code is a bitwise combination of the following values: - `0`: **SUCCESS** - No issues detected. - `1`: **ERRORS** - Critical issues found. - `2`: **WARNINGS** - Non-critical issues detected. - `4`: **INFORMATIONS** - General information messages. - `8`: **HINTS** - Suggestions or improvements. *Examples*: ``` robotcode analyze code robotcode analyze code --filter **/*.robot robotcode analyze code tests/acceptance/first.robot robotcode analyze code -mi DuplicateKeyword tests/acceptance/first.robot robotcode --format json analyze code ``` **Usage:** ```text robotcode analyze code [OPTIONS] [PATHS]... ``` **Options:** - `--version` Show the version and exit. - `-f, --filter PATTERN *` Glob pattern to filter files to analyze. Can be specified multiple times. - `-v, --variable name:value *` Set variables in the test data. see `robot --variable` option. - `-V, --variablefile PATH *` Python or YAML file file to read variables from. see `robot --variablefile` option. - `-P, --pythonpath PATH *` Additional locations where to search test libraries and other extensions when they are imported. see `robot --pythonpath` option. - `-mi, --modifiers-ignore CODE *` Specifies the diagnostics codes to ignore. - `-me, --modifiers-error CODE *` Specifies the diagnostics codes to treat as errors. - `-mw, --modifiers-warning CODE *` Specifies the diagnostics codes to treat as warning. - `-mI, --modifiers-information CODE *` Specifies the diagnostics codes to treat as information. - `-mh, --modifiers-hint CODE *` Specifies the diagnostics codes to treat as hint. - `-xm, --exit-code-mask [error|warn|info|hint|all] *` Specifies which diagnostic severities should not affect the exit code. For example, with 'warn' in the mask, warnings won't cause a non-zero exit code. - `-xe, --extend-exit-code-mask [error|warn|info|hint|all] *` Extend the exit code mask with the specified values. This appends to the default mask, defined in the config file. - `--severity [error|warn|warning|info|information|hint] *` Only report diagnostics of these severities. Repeatable and comma-separated. Filtered-out severities are ignored entirely β€” they don't appear in the output, the summary or the exit code. When omitted, all severities are reported. - `--code CODE *` Only report diagnostics with these codes (e.g. `KeywordNotFound`). Repeatable and comma-separated; matching is case-insensitive. Unlike the modifiers, this filters without changing severity. Combined with --severity, both must match. When omitted, all codes are reported. - `--load-library-timeout SECONDS` Timeout (in seconds) for loading libraries and variable files during analysis. Must be > 0. Overrides config file and environment variable when set. [env var: ROBOTCODE_LOAD_LIBRARY_TIMEOUT] - `--collect-unused / --no-collect-unused` Enable or disable collection of unused keyword and unused variable diagnostics. Overrides the config file setting when specified. - `--cache-namespaces / --no-cache-namespaces` Enable or disable caching of fully analyzed namespace data to disk. Can speed up startup for large projects by skipping re-analysis of unchanged files. - `--show-tracebacks / --no-show-tracebacks` Include the full diagnostic message in the text output, including Python tracebacks and PYTHONPATH listings that Robot Framework appends to import errors. Off by default to keep output concise. Has no effect on JSON output, which always carries the full message. - `--full-paths / --no-full-paths` Show full paths instead of paths relative to the project root. Applies to both text and JSON output. [default: no-full-paths] - `--output-format [concise|json|json-indent|sarif|github|gitlab]` Output format for the analysis result. Overrides the global `--format` for this command. `concise` (default) is the human-readable text output; `sarif` emits a SARIF 2.1.0 log; `github` emits GitHub Actions workflow annotations; `gitlab` emits a GitLab Code Quality report. - `--output-file FILE` Write the report to FILE instead of stdout. Useful with `--output-format sarif`/`gitlab` to produce an artifact for CI upload. - `--help` Show this message and exit. #### config Shows information about the configuration. **Usage:** ```text robotcode config [OPTIONS] COMMAND [ARGS]... ``` **Options:** - `--help` Show this message and exit. **Commands:** - [`files`](#files) Search for configuration files and list them. - [`info`](#info) Shows informations about possible configuration settings. - [`root`](#root) Searches for the root folder of the project and prints them. - [`show`](#show) Shows the current configuration. ##### files Search for configuration files and list them. Takes a list of PATHS or if no PATHS are given, takes the current working directory, to search for configuration files and prints them. Examples: ``` robotcode config files robotcode config files tests/acceptance/first.robot ``` **Usage:** ```text robotcode config files [OPTIONS] [PATHS]... [USER] ``` **Options:** - `--help` Show this message and exit. ##### info Shows informations about possible configuration settings. **Usage:** ```text robotcode config info [OPTIONS] COMMAND [ARGS]... ``` **Options:** - `--help` Show this message and exit. **Commands:** - [`desc`](#desc) Shows the description of the specified configuration settings. - [`list`](#list) Lists all possible configuration settings. ###### desc Shows the description of the specified configuration settings. If no NAME is given shows the description of all possible configuration settings. Wildcards are supported. Examples: ``` robotcode config info desc robotcode config info desc python-path robotcode config info desc rebot.* robotcode config info desc *tag* ``` **Usage:** ```text robotcode config info desc [OPTIONS] [NAME]... ``` **Options:** - `--help` Show this message and exit. ###### list Lists all possible configuration settings. If NAME is given searches for given name. Wildcards are supported. Examples: ``` robotcode config info list robotcode config info list rebot.* robotcode config info list *tag* ``` **Usage:** ```text robotcode config info list [OPTIONS] [NAME]... ``` **Options:** - `--help` Show this message and exit. ##### root Searches for the root folder of the project and prints them. Takes a list of PATHS or if no PATHS are given, takes the current working directory, to search for the root of the project and prints this. Examples: ``` robotcode config root robotcode config root tests/acceptance/first.robot ``` **Usage:** ```text robotcode config root [OPTIONS] [PATHS]... ``` **Options:** - `--help` Show this message and exit. ##### show Shows the current configuration. Takes a list of PATHS or if no PATHS are given, takes the current working directory, to search for configuration files and prints the current configuration. Examples: ``` robotcode config show robotcode config show tests/acceptance/first.robot robotcode --format json config show ``` **Usage:** ```text robotcode config show [OPTIONS] [PATHS]... ``` **Options:** - `-s, --single` Shows single files, not the combined config. - `--help` Show this message and exit. #### debug Starts a Robot Framework debug session and waits for incomming connections. **Usage:** ```text robotcode debug [OPTIONS] [ROBOT_OPTIONS_AND_ARGS]... ``` **Options:** - `--debug / --no-debug` Enable/disable debug mode [default: debug] - `--stop-on-entry / --no-stop-on-entry` Breaks into debugger when a robot framework run starts. [default: no-stop-on-entry] - `--wait-for-client / --no-wait-for-client` Waits until a debug client is connected. [env var: ROBOTCODE_WAIT_FOR_CLIENT; default: wait-for-client] - `--wait-for-client-timeout FLOAT` Timeout in seconds for waiting for a connection with a debug client. [env var: ROBOTCODE_WAIT_FOR_CLIENT_TIMEOUT; default: 15] - `--configuration-done-timeout FLOAT` Timeout to wait for a configuration from client. [env var: ROBOTCODE_CONFIGURATION_DONE_TIMEOUT; default: 15] - `--debugpy / --no-debugpy` Enable/disable python debugging. [env var: ROBOTCODE_DEBUGPY; default: no-debugpy] - `--debugpy-wait-for-client / --no-debugpy-wait-for-client` Waits for a debugpy client to connect. [env var: ROBOTCODE_DEBUGPY_WAIT_FOR_CLIENT] - `--debugpy-port INTEGER` The port for the debugpy session. [default: 5678] - `--output-messages / --no-output-messages` Send output messages from robot framework to client. [default: no-output-messages] - `--output-log / --no-output-log` Send log messages from robotframework to client. [default: output-log] - `--output-timestamps / --no-output-timestamps` Include timestamps in log and output messages. [default: no-output-timestamps] - `--group-output / --no-group-output` Fold/group messages or log messages. [default: no-group-output] - `--tcp [
:]` Run in `tcp` server mode and listen at the given port. (Equivalent to `--mode tcp --port `) *NOTE:* This option is mutually exclusive with options: mode, pipe-name, pipe-server, port. - `--pipe-server NAME` Run in `pipe-server` mode and listen at the given pipe name. (Equivalent to `--mode pipe-server --pipe-name `) *NOTE:* This option is mutually exclusive with options: bind, mode, pipe-name, port, tcp. - `--mode [tcp|pipe_server]` The mode to use for the debug launch server. *NOTE:* This option is mutually exclusive with options: pipe-server, tcp. [env var: ROBOTCODE_MODE; default: TCP] - `--port PORT` The port to listen on or connect to. (Only valid for `tcp` and `socket mode`) *NOTE:* This option is mutually exclusive with options: pipe-name, pipe-server. [env var: ROBOTCODE_PORT; default: 6612; 1<=x<=65535] - `--bind ADDRESS *` Specify alternate bind address. If no address is specified `localhost` is used. (Only valid for tcp and socket mode) *NOTE:* This option is mutually exclusive with options: pipe-name, pipe-server. [env var: ROBOTCODE_BIND; default: 127.0.0.1] - `--pipe-name NAME` The pipe to listen on or connect to. (Only valid in `pipe` and `pipe-server` mode) *NOTE:* This option is mutually exclusive with options: bind, pipe-server, port, tcp. [env var: ROBOTCODE_PIPE_NAME] - `--version` Show the version and exit. - `--help` Show this message and exit. #### debug-launch Launches a robotcode debug session. **Usage:** ```text robotcode debug-launch [OPTIONS] ``` **Options:** - `--stdio` Run in `stdio` mode. (Equivalent to `--mode stdio`) *NOTE:* This option is mutually exclusive with options: bind, mode, pipe, pipe-name, pipe-server, port, socket, tcp. [env var: ROBOTCODE_STDIO] - `--tcp [
:]` Run in `tcp` server mode and listen at the given port. (Equivalent to `--mode tcp --port `) *NOTE:* This option is mutually exclusive with options: mode, pipe, pipe-name, pipe-server, port, socket, stdio. - `--socket [
:]` Run in `socket` mode and connect to the given port. (Equivalent to `--mode socket --port `) *NOTE:* This option is mutually exclusive with options: mode, pipe, pipe-name, pipe-server, port, stdio, tcp. - `--pipe NAME` Run in `pipe` mode and connect to the given pipe name. (Equivalent to `--mode pipe --pipe-name `) *NOTE:* This option is mutually exclusive with options: bind, mode, pipe-name, pipe-server, port, socket, stdio, tcp. - `--pipe-server NAME` Run in `pipe-server` mode and listen at the given pipe name. (Equivalent to `--mode pipe-server --pipe-name `) *NOTE:* This option is mutually exclusive with options: bind, mode, pipe, pipe-name, port, socket, stdio, tcp. - `--mode [stdio|tcp|socket|pipe|pipe_server]` The mode to use for the debug launch server. *NOTE:* This option is mutually exclusive with options: pipe, pipe-server, socket, stdio, tcp. [env var: ROBOTCODE_MODE; default: STDIO] - `--port PORT` The port to listen on or connect to. (Only valid for `tcp` and `socket mode`) *NOTE:* This option is mutually exclusive with options: pipe, pipe-name, pipe-server. [env var: ROBOTCODE_PORT; default: 6611; 1<=x<=65535] - `--bind ADDRESS *` Specify alternate bind address. If no address is specified `localhost` is used. (Only valid for tcp and socket mode) *NOTE:* This option is mutually exclusive with options: pipe, pipe-name, pipe-server. [env var: ROBOTCODE_BIND; default: 127.0.0.1] - `--pipe-name NAME` The pipe to listen on or connect to. (Only valid in `pipe` and `pipe-server` mode) *NOTE:* This option is mutually exclusive with options: bind, pipe, pipe-server, port, socket, stdio, tcp. [env var: ROBOTCODE_PIPE_NAME] - `--version` Show the version and exit. - `--help` Show this message and exit. #### discover Commands to discover informations about the current project. Examples: ``` robotcode discover tests robotcode --profile regression discover tests ``` **Usage:** ```text robotcode discover [OPTIONS] COMMAND [ARGS]... ``` **Options:** - `--diagnostics / --no-diagnostics` List the full `robot` parsing errors and warnings before the results. [default: no-diagnostics] - `--version` Show the version and exit. - `--help` Show this message and exit. **Commands:** - [`all`](#all) Discover suites, tests, tasks with the selected configuration, profiles, options and arguments. - [`files`](#files) Shows all files that are used to discover the tests. - [`info`](#info) Shows some informations about the current *robot* environment. - [`suites`](#suites) Discover suites with the selected configuration, profiles, options and arguments. - [`tags`](#tags) Discover tags with the selected configuration, profiles, options and arguments. - [`tasks`](#tasks) Discover tasks with the selected configuration, profiles, options and arguments. - [`tests`](#tests) Discover tests with the selected configuration, profiles, options and arguments. ##### all Discover suites, tests, tasks with the selected configuration, profiles, options and arguments. You can use all known `robot` arguments to filter for example by tags or to use pre-run-modifier. Examples: ``` robotcode discover all robotcode --profile regression discover all robotcode --profile regression discover all --include regression --exclude wipANDnotready ``` **Usage:** ```text robotcode discover all [OPTIONS] [ROBOT_OPTIONS_AND_ARGS]... ``` **Options:** - `--tags / --no-tags` Show the tags that are present. [default: tags] - `-ebl, --exclude-by-longname TEXT *` Excludes tests/tasks or suites by longname. - `-bl, --by-longname TEXT *` Select tests/tasks or suites by longname. - `--version` Show the version and exit. - `--search TEXT` Only include items where TEXT case-insensitively matches the name, full name, source path, documentation, template name, timeout, any tag (normalisation-aware), the parent suite's Documentation / Metadata, or anything inside the test body β€” keyword names, keyword arguments, assigned variables, FOR/WHILE/IF conditions, VAR/RETURN values, EXCEPT patterns, GROUP names. Mutually exclusive with `--search-regex`. - `--search-regex PATTERN` Only include items where PATTERN (Python regex, case-sensitive β€” prefix with `(?i)` for case-insensitive) matches any of the same targets as `--search`. Mutually exclusive with `--search`. - `--full-paths / --no-full-paths` Show full paths instead of relative. [default: no-full-paths] - `--help` Show this message and exit. Use `-- --help` to see `robot` help. ##### files Shows all files that are used to discover the tests. Note: At the moment only `.robot` and `.resource` files are shown.  Examples: ``` robotcode discover files . ``` **Usage:** ```text robotcode discover files [OPTIONS] [PATHS]... ``` **Options:** - `--full-paths / --no-full-paths` Show full paths instead of relative. [default: no-full-paths] - `--search TEXT` Only include items where TEXT case-insensitively matches the name, full name, source path, documentation, template name, timeout, any tag (normalisation-aware), the parent suite's Documentation / Metadata, or anything inside the test body β€” keyword names, keyword arguments, assigned variables, FOR/WHILE/IF conditions, VAR/RETURN values, EXCEPT patterns, GROUP names. Mutually exclusive with `--search-regex`. - `--search-regex PATTERN` Only include items where PATTERN (Python regex, case-sensitive β€” prefix with `(?i)` for case-insensitive) matches any of the same targets as `--search`. Mutually exclusive with `--search`. - `--help` Show this message and exit. ##### info Shows some informations about the current *robot* environment. Examples: ``` robotcode discover info ``` **Usage:** ```text robotcode discover info [OPTIONS] ``` **Options:** - `--help` Show this message and exit. ##### suites Discover suites with the selected configuration, profiles, options and arguments. You can use all known `robot` arguments to filter for example by tags or to use pre-run-modifier. Examples: ``` robotcode discover suites robotcode --profile regression discover suites robotcode --profile regression discover suites --include regression --exclude wipANDnotready ``` **Usage:** ```text robotcode discover suites [OPTIONS] [ROBOT_OPTIONS_AND_ARGS]... ``` **Options:** - `-ebl, --exclude-by-longname TEXT *` Excludes tests/tasks or suites by longname. - `-bl, --by-longname TEXT *` Select tests/tasks or suites by longname. - `--version` Show the version and exit. - `--search TEXT` Only include items where TEXT case-insensitively matches the name, full name, source path, documentation, template name, timeout, any tag (normalisation-aware), the parent suite's Documentation / Metadata, or anything inside the test body β€” keyword names, keyword arguments, assigned variables, FOR/WHILE/IF conditions, VAR/RETURN values, EXCEPT patterns, GROUP names. Mutually exclusive with `--search-regex`. - `--search-regex PATTERN` Only include items where PATTERN (Python regex, case-sensitive β€” prefix with `(?i)` for case-insensitive) matches any of the same targets as `--search`. Mutually exclusive with `--search`. - `--full-paths / --no-full-paths` Show full paths instead of relative. [default: no-full-paths] - `--help` Show this message and exit. Use `-- --help` to see `robot` help. ##### tags Discover tags with the selected configuration, profiles, options and arguments. You can use all known `robot` arguments to filter for example by tags or to use pre-run-modifier. Examples: ``` robotcode discover tags robotcode --profile regression discover tags robotcode --profile regression discover tags --tests -i wip ``` **Usage:** ```text robotcode discover tags [OPTIONS] [ROBOT_OPTIONS_AND_ARGS]... ``` **Options:** - `--normalized / --not-normalized` Whether or not normalized tags are shown. [default: normalized] - `--tests / --no-tests` Show tests where the tag is present. [default: no-tests] - `--tasks / --no-tasks` Show tasks where the tag is present. [default: no-tasks] - `--full-paths / --no-full-paths` Show full paths instead of relative. [default: no-full-paths] - `-ebl, --exclude-by-longname TEXT *` Excludes tests/tasks or suites by longname. - `-bl, --by-longname TEXT *` Select tests/tasks or suites by longname. - `--version` Show the version and exit. - `--search TEXT` Only include items where TEXT case-insensitively matches the name, full name, source path, documentation, template name, timeout, any tag (normalisation-aware), the parent suite's Documentation / Metadata, or anything inside the test body β€” keyword names, keyword arguments, assigned variables, FOR/WHILE/IF conditions, VAR/RETURN values, EXCEPT patterns, GROUP names. Mutually exclusive with `--search-regex`. - `--search-regex PATTERN` Only include items where PATTERN (Python regex, case-sensitive β€” prefix with `(?i)` for case-insensitive) matches any of the same targets as `--search`. Mutually exclusive with `--search`. - `--help` Show this message and exit. Use `-- --help` to see `robot` help. ##### tasks Discover tasks with the selected configuration, profiles, options and arguments. You can use all known `robot` arguments to filter for example by tags or to use pre-run-modifier. Examples: ``` robotcode discover tasks robotcode --profile regression discover tasks robotcode --profile regression discover tasks --include regression --exclude wipANDnotready ``` **Usage:** ```text robotcode discover tasks [OPTIONS] [ROBOT_OPTIONS_AND_ARGS]... ``` **Options:** - `--tags / --no-tags` Show the tags that are present. [default: no-tags] - `--full-paths / --no-full-paths` Show full paths instead of relative. [default: no-full-paths] - `-ebl, --exclude-by-longname TEXT *` Excludes tests/tasks or suites by longname. - `-bl, --by-longname TEXT *` Select tests/tasks or suites by longname. - `--version` Show the version and exit. - `--search TEXT` Only include items where TEXT case-insensitively matches the name, full name, source path, documentation, template name, timeout, any tag (normalisation-aware), the parent suite's Documentation / Metadata, or anything inside the test body β€” keyword names, keyword arguments, assigned variables, FOR/WHILE/IF conditions, VAR/RETURN values, EXCEPT patterns, GROUP names. Mutually exclusive with `--search-regex`. - `--search-regex PATTERN` Only include items where PATTERN (Python regex, case-sensitive β€” prefix with `(?i)` for case-insensitive) matches any of the same targets as `--search`. Mutually exclusive with `--search`. - `--help` Show this message and exit. Use `-- --help` to see `robot` help. ##### tests Discover tests with the selected configuration, profiles, options and arguments. You can use all known `robot` arguments to filter for example by tags or to use pre-run-modifier. Examples: ``` robotcode discover tests robotcode --profile regression discover tests robotcode --profile regression discover tests --include regression --exclude wipANDnotready ``` **Usage:** ```text robotcode discover tests [OPTIONS] [ROBOT_OPTIONS_AND_ARGS]... ``` **Options:** - `--tags / --no-tags` Show the tags that are present. [default: no-tags] - `--full-paths / --no-full-paths` Show full paths instead of relative. [default: no-full-paths] - `-ebl, --exclude-by-longname TEXT *` Excludes tests/tasks or suites by longname. - `-bl, --by-longname TEXT *` Select tests/tasks or suites by longname. - `--version` Show the version and exit. - `--search TEXT` Only include items where TEXT case-insensitively matches the name, full name, source path, documentation, template name, timeout, any tag (normalisation-aware), the parent suite's Documentation / Metadata, or anything inside the test body β€” keyword names, keyword arguments, assigned variables, FOR/WHILE/IF conditions, VAR/RETURN values, EXCEPT patterns, GROUP names. Mutually exclusive with `--search-regex`. - `--search-regex PATTERN` Only include items where PATTERN (Python regex, case-sensitive β€” prefix with `(?i)` for case-insensitive) matches any of the same targets as `--search`. Mutually exclusive with `--search`. - `--help` Show this message and exit. Use `-- --help` to see `robot` help. #### language-server Run Robot Framework Language Server. **Usage:** ```text robotcode language-server [OPTIONS] [PATHS]... ``` **Options:** - `--stdio` Run in `stdio` mode. (Equivalent to `--mode stdio`) *NOTE:* This option is mutually exclusive with options: bind, mode, pipe, pipe-name, port, socket, tcp. [env var: ROBOTCODE_STDIO] - `--tcp [
:]` Run in `tcp` server mode and listen at the given port. (Equivalent to `--mode tcp --port `) *NOTE:* This option is mutually exclusive with options: mode, pipe, pipe-name, port, socket, stdio. - `--socket [
:]` Run in `socket` mode and connect to the given port. (Equivalent to `--mode socket --port `) *NOTE:* This option is mutually exclusive with options: mode, pipe, pipe-name, port, stdio, tcp. - `--pipe NAME` Run in `pipe` mode and connect to the given pipe name. (Equivalent to `--mode pipe --pipe-name `) *NOTE:* This option is mutually exclusive with options: bind, mode, pipe-name, port, socket, stdio, tcp. - `--mode [stdio|tcp|socket|pipe]` The mode to use for the debug launch server. *NOTE:* This option is mutually exclusive with options: pipe, socket, stdio, tcp. [env var: ROBOTCODE_MODE; default: STDIO] - `--port PORT` The port to listen on or connect to. (Only valid for `tcp` and `socket mode`) *NOTE:* This option is mutually exclusive with options: pipe, pipe-name. [env var: ROBOTCODE_PORT; default: 6610; 1<=x<=65535] - `--bind ADDRESS *` Specify alternate bind address. If no address is specified `localhost` is used. (Only valid for tcp and socket mode) *NOTE:* This option is mutually exclusive with options: pipe, pipe-name. [env var: ROBOTCODE_BIND; default: 127.0.0.1] - `--pipe-name NAME` The pipe to listen on or connect to. (Only valid in `pipe` and `pipe-server` mode) *NOTE:* This option is mutually exclusive with options: bind, pipe, port, socket, stdio, tcp. [env var: ROBOTCODE_PIPE_NAME] - `--version` Show the version and exit. - `--help` Show this message and exit. #### libdoc Runs `libdoc` with the selected configuration, profiles, options and arguments. The options and arguments are passed to `libdoc` as is. **Usage:** ```text robotcode libdoc [OPTIONS] [ROBOT_OPTIONS_AND_ARGS]... ``` **Options:** - `--version` Show the version and exit. - `--help` Show this message and exit. Use `-- --help` to see the `libdoc` help. #### profiles Shows information on defined profiles. **Usage:** ```text robotcode profiles [OPTIONS] COMMAND [ARGS]... ``` **Options:** - `--help` Show this message and exit. **Commands:** - [`list`](#list) Lists the defined profiles in the current configuration. - [`show`](#show) Shows the given profile configuration. ##### list Lists the defined profiles in the current configuration. **Usage:** ```text robotcode profiles list [OPTIONS] [PATHS]... ``` **Options:** - `-h, --show-hidden` Show hidden profiles. - `-sp, --sort-by-precedence` Sort by precedence. - `--help` Show this message and exit. ##### show Shows the given profile configuration. **Usage:** ```text robotcode profiles show [OPTIONS] [PATHS]... ``` **Options:** - `-n, --no-evaluate` Don't evaluate expressions in the profile. - `--help` Show this message and exit. #### rebot Runs `rebot` with the selected configuration, profiles, options and arguments. The options and arguments are passed to `rebot` as is. **Usage:** ```text robotcode rebot [OPTIONS] [ROBOT_OPTIONS_AND_ARGS]... ``` **Options:** - `--version` Show the version and exit. - `--help` Show this message and exit. Use `-- --help` to see `rebot` help. #### repl Run Robot Framework interactively (alias `shell`). Starts an interactive session where you enter Robot Framework keywords and run them immediately. Pass FILES to execute them in the session. **Usage:** ```text robotcode repl [OPTIONS] [FILES]... ``` **Options:** - `--no-history` Don't load or save the persistent history file. In-session arrow-up recall still works, but nothing crosses session boundaries. Useful for AI-agent invocations or quick spike sessions you don't want polluting your shell's REPL history. - `--backend [auto|prompt-toolkit|plain]` Force a specific input backend instead of auto-picking. `auto` and `prompt-toolkit` both pick the prompt-toolkit-driven interpreter (completion, syntax highlighting, history, doc viewer). `plain` drops to a bare `input()` prompt β€” useful when ANSI escapes or popups would interfere with the surrounding capture. [default: auto] - `--plain` Shorthand for `--backend=plain`. Disables all prompt enhancements β€” completion, syntax highlighting, candidate popup, auto-suggest, history file. The prompt becomes a bare `input()` call. Recommended for AI-agent invocations, automation pipelines, and any context where ANSI escapes or completion popups would interfere with stdin/stdout capture. Conflicts with `--backend=`. - `-v, --variable name:value *` Set variables in the test data. See `robot --variable` option. - `-V, --variablefile PATH *` Python or YAML file to read variables from. See `robot --variablefile` option. - `-P, --pythonpath PATH *` Additional locations where to search test libraries and other extensions when they are imported. See `robot --pythonpath` option. - `-k, --show-keywords` Executed keywords will be shown in the output. - `-i, --inspect` Activate inspection mode. This forces a prompt to appear after the REPL script is executed. - `-d, --outputdir DIR` Where to create output files. See `robot --outputdir` option. - `-o, --output FILE` XML output file. See `robot --output` option. - `-r, --report FILE` HTML output file. See `robot --report` option. - `-l, --log FILE` HTML log file. See `robot --log` option. - `-x, --xunit FILE` xUnit output file. See `robot --xunit` option. - `-s, --source FILE` Use the parent directory of FILE as the REPL's working directory. Relative paths inside `Import Resource`, `Import Library`, file-based variables, etc. resolve against that directory. The file itself is never read or written, so the path doesn't need to exist. - `--debugger-attached / --no-debugger-attached` Whether the debugger is active. While detached nothing pauses β€” a failing keyword just prints its error and you stay at the prompt β€” but breakpoints and exception filters stay configured. Default: attached for `robot-debug`; for `repl` detached, unless a pause trigger (`--break`, a `--break-on-*` flag) is given. Toggle at runtime with `.debug on` / `.debug off`. - `--break LOCATION *` Break at LOCATION β€” a `file:line` or a keyword name. Repeatable. - `--break-on-exception / --no-break-on-exception` Break at an uncaught failing keyword (not caught by TRY/EXCEPT or `Run Keyword And …`), before the failure unwinds. Armed by default; it only pauses while the debugger is attached (see `--debugger-attached`). - `--break-on-all-exceptions / --no-break-on-all-exceptions` Break at EVERY failing keyword, even ones caught by TRY/EXCEPT or `Run Keyword And …`. [default: no-break-on-all-exceptions] - `--break-on-failed-test / --no-break-on-failed-test` Break at the end of a failing test. [default: no-break-on-failed-test] - `--break-on-failed-suite / --no-break-on-failed-suite` Break at the end of a failing suite. [default: no-break-on-failed-suite] - `--version` Show the version and exit. - `--help` Show this message and exit. #### repl-server Start a REPL server, client can connect to the server and run the REPL scripts. **Usage:** ```text robotcode repl-server [OPTIONS] [FILES]... ``` **Options:** - `--stdio` Run in `stdio` mode. (Equivalent to `--mode stdio`) *NOTE:* This option is mutually exclusive with options: bind, mode, pipe, pipe-name, pipe-server, port, socket, tcp. [env var: ROBOTCODE_STDIO] - `--tcp [
:]` Run in `tcp` server mode and listen at the given port. (Equivalent to `--mode tcp --port `) *NOTE:* This option is mutually exclusive with options: mode, pipe, pipe-name, pipe-server, port, socket, stdio. - `--socket [
:]` Run in `socket` mode and connect to the given port. (Equivalent to `--mode socket --port `) *NOTE:* This option is mutually exclusive with options: mode, pipe, pipe-name, pipe-server, port, stdio, tcp. - `--pipe NAME` Run in `pipe` mode and connect to the given pipe name. (Equivalent to `--mode pipe --pipe-name `) *NOTE:* This option is mutually exclusive with options: bind, mode, pipe-name, pipe-server, port, socket, stdio, tcp. - `--pipe-server NAME` Run in `pipe-server` mode and listen at the given pipe name. (Equivalent to `--mode pipe-server --pipe-name `) *NOTE:* This option is mutually exclusive with options: bind, mode, pipe, pipe-name, port, socket, stdio, tcp. - `--mode [stdio|tcp|socket|pipe|pipe_server]` The mode to use for the debug launch server. *NOTE:* This option is mutually exclusive with options: pipe, pipe-server, socket, stdio, tcp. [env var: ROBOTCODE_MODE; default: STDIO] - `--port PORT` The port to listen on or connect to. (Only valid for `tcp` and `socket mode`) *NOTE:* This option is mutually exclusive with options: pipe, pipe-name, pipe-server. [env var: ROBOTCODE_PORT; default: 6601; 1<=x<=65535] - `--bind ADDRESS *` Specify alternate bind address. If no address is specified `localhost` is used. (Only valid for tcp and socket mode) *NOTE:* This option is mutually exclusive with options: pipe, pipe-name, pipe-server. [env var: ROBOTCODE_BIND; default: 127.0.0.1] - `--pipe-name NAME` The pipe to listen on or connect to. (Only valid in `pipe` and `pipe-server` mode) *NOTE:* This option is mutually exclusive with options: bind, pipe, pipe-server, port, socket, stdio, tcp. [env var: ROBOTCODE_PIPE_NAME] - `-v, --variable name:value *` Set variables in the test data. see `robot --variable` option. - `-V, --variablefile PATH *` Python or YAML file file to read variables from. see `robot --variablefile` option. - `-P, --pythonpath PATH *` Additional locations where to search test libraries and other extensions when they are imported. see `robot --pythonpath` option. - `-d, --outputdir DIR` Where to create output files. see `robot --outputdir` option. - `-o, --output FILE` XML output file. see `robot --output` option. - `-r, --report FILE` HTML output file. see `robot --report` option. - `-l, --log FILE` HTML log file. see `robot --log` option. - `-x, --xunit FILE` xUnit output file. see `robot --xunit` option. - `--version` Show the version and exit. - `-s, --source FILE` Use the parent directory of FILE as the REPL's working directory. Relative paths inside `Import Resource`, `Import Library`, file-based variables, etc. resolve against that directory. The file itself is never read or written, so the path doesn't need to exist. - `--help` Show this message and exit. #### results Inspect a finished run's `output.xml` / `output.json` β€” counts, failures, and per-test execution tree, without re-running. The result file is auto-discovered from the active profile's `output_dir` / `output` settings; override with `-o/--output PATH`. Use `-f json` (or `toml`) for a structured payload. Examples: ``` robotcode results summary robotcode results summary --failed robotcode results show --failed robotcode results log "*Login*" robotcode --format json results summary ``` **Usage:** ```text robotcode results [OPTIONS] COMMAND [ARGS]... ``` **Options:** - `--help` Show this message and exit. **Commands:** - [`diff`](#diff) Compare two output files: status changes plus added/removed tests. - [`log`](#log) Show the execution log of each test: keywords, control flow and messages. - [`show`](#show) List individual tests with status, source and failure message. - [`stats`](#stats) Aggregate results by tag, suite, or status. - [`summary`](#summary) Print headline counts and overall status for a finished run. ##### diff Compare two output files: status changes plus added/removed tests. If `CURRENT` is omitted, it is auto-discovered from the active profile so you can diff a saved baseline against the latest run. Examples: ``` robotcode results diff baseline.xml robotcode results diff prev/output.xml curr/output.xml robotcode results diff baseline.xml --only new-failures robotcode results diff baseline.xml -i smoke robotcode results diff baseline.xml --search TimeoutError robotcode --format json results diff baseline.xml ``` **Usage:** ```text robotcode results diff [OPTIONS] BASELINE [CURRENT] ``` **Options:** - `--status [pass|fail|skip|not-run] *` Only include tests with one of these statuses. - `-i, --include TAG_PATTERN *` Include tests matching the tag pattern. Supports Robot's tag pattern syntax (AND, OR, NOT, *, ?). - `-e, --exclude TAG_PATTERN *` Exclude tests matching the tag pattern. Same syntax as --include. - `-s, --suite NAME *` Only include tests inside the named suite (glob against full suite name). - `-t, --test, --task NAME *` Only include tests whose name matches (glob against full test name). `--task` is an alias for `--test` (Robot's RPA terminology). - `-bl, --by-longname NAME *` Select tests/tasks or suites by long name (exact match). - `-ebl, --exclude-by-longname NAME *` Exclude tests/tasks or suites by long name (exact match). - `--search TEXT` Only include tests with at least one case-insensitive substring match against TEXT. Searches test name, full name, failure message, documentation, template name, timeout, tags, the parent suite's Documentation / Metadata, every executed keyword's name / arguments / [Documentation] / [Tags] / [Timeout] / failure message, and log messages. Mutually exclusive with `--search-regex`. - `--search-regex PATTERN` Only include tests with at least one match against PATTERN (Python regular expression, case-sensitive β€” prefix with `(?i)` for case-insensitive). Same target fields as `--search`. Mutually exclusive with `--search`. - `--full-paths / --no-full-paths` Show absolute source paths instead of paths relative to cwd. [default: no-full-paths] - `--message-chars INTEGER RANGE` Truncate failure messages to N characters (0 = no truncation). [default: 120; x>=0] - `--only [new-failures|new-passes|status-changes|added|removed] *` Restrict output to these categories. Default: all. - `--help` Show this message and exit. ##### log Show the execution log of each test: keywords, control flow and messages. Filter the same way as `show` β€” by status, tag, suite, or test name. Without filters, all tests are included. Use `--max-depth` to collapse deeply nested keyword calls. Examples: ``` robotcode results log robotcode results log --failed robotcode results log -t "*Login*" robotcode results log --level WARN robotcode results log --max-depth 2 robotcode results log -i smoke --extract /tmp/artefacts robotcode results log --search "TimeoutError" robotcode results log --execution-messages ``` **Usage:** ```text robotcode results log [OPTIONS] ``` **Options:** - `--status [pass|fail|skip|not-run] *` Only include tests with one of these statuses. - `-i, --include TAG_PATTERN *` Include tests matching the tag pattern. Supports Robot's tag pattern syntax (AND, OR, NOT, *, ?). - `-e, --exclude TAG_PATTERN *` Exclude tests matching the tag pattern. Same syntax as --include. - `-s, --suite NAME *` Only include tests inside the named suite (glob against full suite name). - `-t, --test, --task NAME *` Only include tests whose name matches (glob against full test name). `--task` is an alias for `--test` (Robot's RPA terminology). - `-bl, --by-longname NAME *` Select tests/tasks or suites by long name (exact match). - `-ebl, --exclude-by-longname NAME *` Exclude tests/tasks or suites by long name (exact match). - `--failed` Shortcut for `--status fail`. Additive with `--status` / `--passed` / `--skipped`. - `--passed` Shortcut for `--status pass`. Additive with `--status` / `--failed` / `--skipped`. - `--skipped` Shortcut for `--status skip`. Additive with `--status` / `--failed` / `--passed`. - `--search TEXT` Only include tests with at least one case-insensitive substring match against TEXT. Searches test name, full name, failure message, documentation, template name, timeout, tags, the parent suite's Documentation / Metadata, every executed keyword's name / arguments / [Documentation] / [Tags] / [Timeout] / failure message, and log messages. Mutually exclusive with `--search-regex`. - `--search-regex PATTERN` Only include tests with at least one match against PATTERN (Python regular expression, case-sensitive β€” prefix with `(?i)` for case-insensitive). Same target fields as `--search`. Mutually exclusive with `--search`. - `-o, --output PATH` Path to output.xml/output.json (Robot's `--output`). If omitted, auto-discovered from the active profile's `output_dir` + `output` settings (with timestamp glob fallback and ./output.xml as last resort). A directory may also be passed β€” then auto-discovery happens inside it. - `--level [trace|debug|info|warn|error|fail]` Minimum message level to include. [default: INFO] - `--max-depth N` Limit nested keyword calls to N levels (0 = unlimited). When a keyword sits below the limit, its body is collapsed and the hidden child count is shown instead. [default: 0; x>=0] - `--extract DIRECTORY` Copy/decode referenced artefacts into this directory. Each test's artefacts go into a per-test subdirectory. - `--full-paths / --no-full-paths` [default: no-full-paths] - `--timestamps / --no-timestamps` Show timestamps next to log messages. [default: no-timestamps] - `--timing / --no-timing` Show start time per test/keyword and append start / end / elapsed of the run as a footer. Use `--no-timing` to suppress. [default: timing] - `--raw-html / --no-raw-html` Emit HTML messages as raw markup instead of converting them to plain text. Useful when the HTML is the payload of interest. Embedded base64 images and external file refs are NOT extracted in raw mode. [default: no-raw-html] - `--execution-messages / --no-execution-messages` Also show parser/discovery messages from output.xml's `` section (deduplicated). [default: no-execution-messages] - `--keyword-info / --no-keyword-info` Include each executed keyword's [Documentation], [Tags] and [Timeout] from the keyword definition. Off by default to keep the log compact. [default: no-keyword-info] - `--suite-info / --no-suite-info` Group tests under suite headers (name, source, Documentation, Metadata, status). In JSON, populates `suites` and a per-test `suite` reference. Off by default to keep the log compact. [default: no-suite-info] - `--help` Show this message and exit. ##### show List individual tests with status, source and failure message. One line per test: status badge, full name, `(path:line)` link, and the first line of any failure/skip message. Examples: ``` robotcode results show robotcode results show --failed robotcode results show --failed --skipped --tags robotcode results show -i smoke -e wipANDnotready robotcode results show -s "MyProject.Login.*" robotcode results show --top 20 robotcode results show --search "AssertionError" ``` **Usage:** ```text robotcode results show [OPTIONS] ``` **Options:** - `--status [pass|fail|skip|not-run] *` Only include tests with one of these statuses. - `-i, --include TAG_PATTERN *` Include tests matching the tag pattern. Supports Robot's tag pattern syntax (AND, OR, NOT, *, ?). - `-e, --exclude TAG_PATTERN *` Exclude tests matching the tag pattern. Same syntax as --include. - `-s, --suite NAME *` Only include tests inside the named suite (glob against full suite name). - `-t, --test, --task NAME *` Only include tests whose name matches (glob against full test name). `--task` is an alias for `--test` (Robot's RPA terminology). - `-bl, --by-longname NAME *` Select tests/tasks or suites by long name (exact match). - `-ebl, --exclude-by-longname NAME *` Exclude tests/tasks or suites by long name (exact match). - `--failed` Shortcut for `--status fail`. Additive with `--status` / `--passed` / `--skipped`. - `--passed` Shortcut for `--status pass`. Additive with `--status` / `--failed` / `--skipped`. - `--skipped` Shortcut for `--status skip`. Additive with `--status` / `--failed` / `--passed`. - `--search TEXT` Only include tests with at least one case-insensitive substring match against TEXT. Searches test name, full name, failure message, documentation, template name, timeout, tags, the parent suite's Documentation / Metadata, every executed keyword's name / arguments / [Documentation] / [Tags] / [Timeout] / failure message, and log messages. Mutually exclusive with `--search-regex`. - `--search-regex PATTERN` Only include tests with at least one match against PATTERN (Python regular expression, case-sensitive β€” prefix with `(?i)` for case-insensitive). Same target fields as `--search`. Mutually exclusive with `--search`. - `-o, --output PATH` Path to output.xml/output.json (Robot's `--output`). If omitted, auto-discovered from the active profile's `output_dir` + `output` settings (with timestamp glob fallback and ./output.xml as last resort). A directory may also be passed β€” then auto-discovery happens inside it. - `--top INTEGER RANGE` Show at most N tests (0 = no limit, default). [default: 0; x>=0] - `--message-chars INTEGER RANGE` Truncate each message to N characters (0 = no truncation). [default: 120; x>=0] - `--full-paths / --no-full-paths` Show absolute source paths instead of paths relative to cwd. [default: no-full-paths] - `--tags / --no-tags` Append the tag list after each test. [default: no-tags] - `--timing / --no-timing` Show start time per test and append start / end / elapsed of the run to the statistics block. Use `--no-timing` to suppress. [default: timing] - `--sort FIELD` Sort tests before display. `name`/`suite` = lexicographic full-name/suite. `status` = FAIL β†’ SKIP β†’ PASS β†’ NOT RUN. `elapsed` = duration (longest first). `start` = start time. Default: execution order from the output file. - `--reverse / --no-reverse` Reverse the sort order (only applies with `--sort`). [default: no-reverse] - `--help` Show this message and exit. ##### stats Aggregate results by tag, suite, or status. Each section is a table with pass/fail/skip counts and total elapsed per group. Repeat `--by` to render multiple sections in one go. Examples: ``` robotcode results stats robotcode results stats --by tag robotcode results stats --by tag --by suite robotcode results stats --by tag --sort elapsed --top 20 robotcode results stats --by tag --search Browser robotcode --format json results stats --by tag ``` **Usage:** ```text robotcode results stats [OPTIONS] ``` **Options:** - `--status [pass|fail|skip|not-run] *` Only include tests with one of these statuses. - `-i, --include TAG_PATTERN *` Include tests matching the tag pattern. Supports Robot's tag pattern syntax (AND, OR, NOT, *, ?). - `-e, --exclude TAG_PATTERN *` Exclude tests matching the tag pattern. Same syntax as --include. - `-s, --suite NAME *` Only include tests inside the named suite (glob against full suite name). - `-t, --test, --task NAME *` Only include tests whose name matches (glob against full test name). `--task` is an alias for `--test` (Robot's RPA terminology). - `-bl, --by-longname NAME *` Select tests/tasks or suites by long name (exact match). - `-ebl, --exclude-by-longname NAME *` Exclude tests/tasks or suites by long name (exact match). - `--failed` Shortcut for `--status fail`. Additive with `--status` / `--passed` / `--skipped`. - `--passed` Shortcut for `--status pass`. Additive with `--status` / `--failed` / `--skipped`. - `--skipped` Shortcut for `--status skip`. Additive with `--status` / `--failed` / `--passed`. - `--search TEXT` Only include tests with at least one case-insensitive substring match against TEXT. Searches test name, full name, failure message, documentation, template name, timeout, tags, the parent suite's Documentation / Metadata, every executed keyword's name / arguments / [Documentation] / [Tags] / [Timeout] / failure message, and log messages. Mutually exclusive with `--search-regex`. - `--search-regex PATTERN` Only include tests with at least one match against PATTERN (Python regular expression, case-sensitive β€” prefix with `(?i)` for case-insensitive). Same target fields as `--search`. Mutually exclusive with `--search`. - `-o, --output PATH` Path to output.xml/output.json (Robot's `--output`). If omitted, auto-discovered from the active profile's `output_dir` + `output` settings (with timestamp glob fallback and ./output.xml as last resort). A directory may also be passed β€” then auto-discovery happens inside it. - `--by [tag|suite|status] *` Group tests by this attribute (one section per value). [default: status] - `--sort [name|total|failed|elapsed]` Within each section: sort groups by this metric (descending). [default: failed] - `--top INTEGER RANGE` Show at most N groups per section (0 = all). [default: 0; x>=0] - `--help` Show this message and exit. ##### summary Print headline counts and overall status for a finished run. Pass `--failed` to also list failed tests above the counts. Filter options narrow what is counted. Examples: ``` robotcode results summary robotcode results summary --failed robotcode results summary -i smoke --status fail robotcode results summary --search TimeoutError robotcode --format json results summary ``` **Usage:** ```text robotcode results summary [OPTIONS] ``` **Options:** - `--status [pass|fail|skip|not-run] *` Only include tests with one of these statuses. - `-i, --include TAG_PATTERN *` Include tests matching the tag pattern. Supports Robot's tag pattern syntax (AND, OR, NOT, *, ?). - `-e, --exclude TAG_PATTERN *` Exclude tests matching the tag pattern. Same syntax as --include. - `-s, --suite NAME *` Only include tests inside the named suite (glob against full suite name). - `-t, --test, --task NAME *` Only include tests whose name matches (glob against full test name). `--task` is an alias for `--test` (Robot's RPA terminology). - `-bl, --by-longname NAME *` Select tests/tasks or suites by long name (exact match). - `-ebl, --exclude-by-longname NAME *` Exclude tests/tasks or suites by long name (exact match). - `--search TEXT` Only include tests with at least one case-insensitive substring match against TEXT. Searches test name, full name, failure message, documentation, template name, timeout, tags, the parent suite's Documentation / Metadata, every executed keyword's name / arguments / [Documentation] / [Tags] / [Timeout] / failure message, and log messages. Mutually exclusive with `--search-regex`. - `--search-regex PATTERN` Only include tests with at least one match against PATTERN (Python regular expression, case-sensitive β€” prefix with `(?i)` for case-insensitive). Same target fields as `--search`. Mutually exclusive with `--search`. - `-o, --output PATH` Path to output.xml/output.json (Robot's `--output`). If omitted, auto-discovered from the active profile's `output_dir` + `output` settings (with timestamp glob fallback and ./output.xml as last resort). A directory may also be passed β€” then auto-discovery happens inside it. - `--failed / --no-failed` Include the list of failed tests (with messages) above the counts table. [default: no-failed] - `--full-paths / --no-full-paths` Show absolute source paths instead of paths relative to cwd. [default: no-full-paths] - `--help` Show this message and exit. #### robot Runs `robot` with the selected configuration, profiles, options and arguments. The options and arguments are passed to `robot` as is. Examples: ``` robotcode robot robotcode robot tests robotcode robot -i regression -e wip tests robotcode --profile ci robot -i regression -e wip tests ``` **Usage:** ```text robotcode robot [OPTIONS] [ROBOT_OPTIONS_AND_ARGS]... ``` **Options:** - `-ebl, --exclude-by-longname TEXT *` Excludes tests/tasks or suites by longname. - `-bl, --by-longname TEXT *` Select tests/tasks or suites by longname. - `--version` Show the version and exit. - `--help` Show this message and exit. Use `-- --help` to see `robot` help. #### robot-debug Run a real Robot Framework suite with the debugger attached (alias `run- debug`). Takes the same arguments as `robotcode robot`, but pauses at breakpoints so you can inspect and step through the run at a debug prompt. **Usage:** ```text robotcode robot-debug [OPTIONS] [ROBOT_OPTIONS_AND_ARGS]... ``` **Options:** - `--no-history` Don't load or save the persistent history file. In-session arrow-up recall still works, but nothing crosses session boundaries. Useful for AI-agent invocations or quick spike sessions you don't want polluting your shell's REPL history. - `--backend [auto|prompt-toolkit|plain]` Force a specific input backend instead of auto-picking. `auto` and `prompt-toolkit` both pick the prompt-toolkit-driven interpreter (completion, syntax highlighting, history, doc viewer). `plain` drops to a bare `input()` prompt β€” useful when ANSI escapes or popups would interfere with the surrounding capture. [default: auto] - `--plain` Shorthand for `--backend=plain`. Disables all prompt enhancements β€” completion, syntax highlighting, candidate popup, auto-suggest, history file. The prompt becomes a bare `input()` call. Recommended for AI-agent invocations, automation pipelines, and any context where ANSI escapes or completion popups would interfere with stdin/stdout capture. Conflicts with `--backend=`. - `-ebl, --exclude-by-longname TEXT *` Excludes tests/tasks or suites by longname. - `-bl, --by-longname TEXT *` Select tests/tasks or suites by longname. - `--debugger-attached / --no-debugger-attached` Whether the debugger is active. While detached nothing pauses β€” a failing keyword just prints its error and you stay at the prompt β€” but breakpoints and exception filters stay configured. Default: attached for `robot-debug`; for `repl` detached, unless a pause trigger (`--break`, a `--break-on-*` flag) is given. Toggle at runtime with `.debug on` / `.debug off`. - `--break LOCATION *` Break at LOCATION β€” a `file:line` or a keyword name. Repeatable. - `--break-on-exception / --no-break-on-exception` Break at an uncaught failing keyword (not caught by TRY/EXCEPT or `Run Keyword And …`), before the failure unwinds. Armed by default; it only pauses while the debugger is attached (see `--debugger-attached`). - `--break-on-all-exceptions / --no-break-on-all-exceptions` Break at EVERY failing keyword, even ones caught by TRY/EXCEPT or `Run Keyword And …`. [default: no-break-on-all-exceptions] - `--break-on-failed-test / --no-break-on-failed-test` Break at the end of a failing test. [default: no-break-on-failed-test] - `--break-on-failed-suite / --no-break-on-failed-suite` Break at the end of a failing suite. [default: no-break-on-failed-suite] - `--stop-on-entry` Break at the very first keyword. - `--version` Show the version and exit. - `--help` Show this message and exit. Use `-- --help` to see `robot` help. #### testdoc Runs `testdoc` with the selected configuration, profiles, options and arguments. The options and arguments are passed to `testdoc` as is. **Usage:** ```text robotcode testdoc [OPTIONS] [ROBOT_OPTIONS_AND_ARGS]... ``` **Options:** - `--version` Show the version and exit. - `--help` Show this message and exit. Use `-- --help` to see `testdoc` help. ## Getting Help The command reference above is generated directly from the CLI, so it always matches the installed version. To get the same information on the command line, append `--help` to any command or sub-command, for example `robotcode analyze --help` or `robotcode results summary --help`. For the commands that wrap a standard Robot Framework tool (`robot`, `rebot`, `libdoc`, `testdoc`), use `-- --help` to see the help of the underlying tool, e.g. `robotcode robot -- --help`. ## See Also - [Configuration](./config.md) β€” how `robot.toml` and profiles work, the foundation for the `config` and `profiles` commands. - [Discovering Tests](./discovering-tests.md) β€” details on the `discover` command. - [Analyzing Results](./analyzing-results.md) β€” working with the `analyze` and `results` commands. - [REPL](./repl.md) β€” using the interactive `repl` shell. --- URL: "/03_reference/config" LLMS_URL: "/03_reference/config.md" --- # robot.toml configuration settings ## [profile].description Type: `str | None` Description of the profile. ## [profile].detached Type: `bool | None` The profile should be detached. Detached means it is not inherited from the main profile. ## [profile].enabled Type: `bool | Condition | None` If enabled the profile is used. You can also use and `if` condition to calculate the enabled state. Examples: ```toml # always disabled enabled = false ``` ```toml # enabled if TEST_VAR is set enabled = { if = 'environ.get("CI") == "true"' } ``` ## [profile].hidden Type: `bool | Condition | None` The profile should be hidden. Hidden means it is not shown in the list of available profiles. Examples: ```toml hidden = true ``` ```toml hidden = { if = 'environ.get("CI") == "true"' } ``` ## [profile].inherits Type: `str | StringExpression | list[str | StringExpression] | None` Profiles to inherit from. Examples: ```toml inherits = ["default", "Firefox"] ``` ## [profile].precedence Type: `int | None` Precedence of the profile. Lower values are executed first. If not set the order is undefined. ## args Type: `list[str] | None` Arguments to be passed to _robot_. Examples: ```toml args = ["-t", "abc"] ``` ## console Type: `Literal['verbose', 'dotted', 'skipped', 'quiet', 'none'] | None` How to report execution on the console. **verbose:** report every suite and test (default) **dotted:** only show `.` for passed test, `s` for skipped tests, and `F` for failed tests **quiet:** no output except for errors and warnings **none:** no output whatsoever Examples: ```toml console = "dotted" ``` corresponds to the `--console type` option of _robot_ ## console-colors Type: `Literal['auto', 'on', 'ansi', 'off'] | None` Use colors on console output or not. **auto:** use colors when output not redirected (default) **on:** always use colors **ansi:** like `on` but use ANSI colors also on Windows **off:** disable colors altogether Examples: ```toml console-colors = "on" ``` corresponds to the `-C --consolecolors auto|on|ansi|off` option of _robot_ ## console-links Type: `Literal['auto', 'off'] | None` Control making paths to results files hyperlinks. **auto:** use links when colors are enabled (default) **off:** disable links unconditionally Examples: ```toml console-links = "off" ``` corresponds to the `--consolelinks auto|off` option of _robot_ ## console-markers Type: `Literal['auto', 'on', 'off'] | None` Show markers on the console when top level keywords in a test case end. Values have same semantics as with --consolecolors. Examples: ```toml console-markers = "off" ``` corresponds to the `-K --consolemarkers auto|on|off` option of _robot_ ## console-width Type: `int | None` Width of the console output. Default is 78. Examples: ```toml console-width = 100 ``` corresponds to the `-W --consolewidth chars` option of _robot_ ## debug-file Type: `str | StringExpression | None` Debug file written during execution. Not created unless this option is specified. Examples: ```toml debug-file = "debug.log" ``` corresponds to the `-b --debugfile file` option of _robot_ ## default-profiles Type: `str | list[str] | None` Selects the Default profile if no profile is given at command line. Examples: ```toml default-profiles = "default" ``` ```toml default-profiles = ["default", "Firefox"] ``` ## doc Type: `str | StringExpression | None` Set the documentation of the top level suite. Simple formatting is supported (e.g. *bold*). If the documentation contains spaces, it must be quoted. If the value is path to an existing file, actual documentation is read from that file. Examples: ```toml doc = "Very *good* example" ``` ```toml # read documentation from a file doc = "doc_from_file.txt" ``` corresponds to the `-D --doc documentation` option of _robot_ ## dotted Type: `bool | Flag | None` Shortcut for `--console dotted`. Examples: ```toml dotted = true ``` corresponds to the `-. --dotted` option of _robot_ ## dry-run Type: `bool | Flag | None` Verifies test data and runs tests so that library keywords are not executed. Examples: ```toml dry-run = true ``` corresponds to the `--dryrun` option of _robot_ ## env Type: `dict[str, str | StringExpression] | None` Define environment variables to be set before running tests. Examples: ```toml [env] TEST_VAR = "test" SECRET = "password" ``` ## excludes Type: `list[str | StringExpression] | None` Select test cases not to run by tag. These tests are not run even if included with --include. Tags are matched using same rules as with --include. Examples: ```toml excludes = ["smoke", "wip*"] ``` corresponds to the `-e --exclude tag *` option of _robot_ ## exit-on-error Type: `bool | Flag | None` Stops test execution if any error occurs when parsing test data, importing libraries, and so on. Examples: ```toml exit-on-error = true ``` corresponds to the `--exitonerror` option of _robot_ ## exit-on-failure Type: `bool | Flag | None` Stops test execution if any test fails. Examples: ```toml exit-on-failure = true ``` corresponds to the `-X --exitonfailure` option of _robot_ ## expand-keywords Type: `list[str | NamePattern | TagPattern] | None` Matching keywords will be automatically expanded in the log file. Matching against keyword name or tags work using same rules as with --removekeywords. Examples: ```toml expand-keywords = ["name:BuiltIn.Log", "tag:expand"] ``` corresponds to the `--expandkeywords name:|tag: *` option of _robot_ ## extend-args Type: `list[str] | None` Append extra arguments to be passed to _robot_. Examples: ```toml extend-args = ["-t", "abc"] ``` ## extend-env Type: `dict[str, str | StringExpression] | None` Append extra environment variables to be set before run. Examples: ```toml [extend-env] EXTRA_VAR = "value" ``` ## extend-excludes Type: `list[str | StringExpression] | None` Appends entries to the --exclude option. Select test cases not to run by tag. These tests are not run even if included with --include. Tags are matched using same rules as with --include. Examples: ```toml extend-excludes = ["smoke", "wip*"] ``` corresponds to the `-e --exclude tag *` option of _robot_ ## extend-expand-keywords Type: `list[str | NamePattern | TagPattern] | None` Appends entries to the --expandkeywords option. Matching keywords will be automatically expanded in the log file. Matching against keyword name or tags work using same rules as with --removekeywords. Examples: ```toml extend-expand-keywords = ["name:BuiltIn.Log", "tag:expand"] ``` corresponds to the `--expandkeywords name:|tag: *` option of _robot_ ## extend-flatten-keywords Type: `list[str | Literal['for', 'while', 'iteration'] | NamePattern | TagPattern] | None` Appends entries to the --flattenkeywords option. Flattens matching keywords in the generated log file. Matching keywords get all log messages from their child keywords and children are discarded otherwise. **for:** flatten FOR loops fully **while:** flatten WHILE loops fully **iteration:** flatten FOR/WHILE loop iterations **foritem:** deprecated alias for `iteration` **name:\:** flatten matched keywords using same matching rules as with `--removekeywords name:` **tag:\:** flatten matched keywords using same matching rules as with `--removekeywords tag:` Examples: ```toml extend-flatten-keywords = ["for", "name:Lib.HugeKw", "tag:flatten"] ``` corresponds to the `--flattenkeywords for|while|iteration|name:|tag: *` option of _robot_ ## extend-includes Type: `list[str | StringExpression] | None` Appends entries to the --include option. Select tests by tag. Similarly as name with --test, tag is case and space insensitive and it is possible to use patterns with `*`, `?` and `[]` as wildcards. Tags and patterns can also be combined together with `AND`, `OR`, and `NOT` operators. Examples: ```toml # match tests tagged "foo" or "bar*" extend-includes = ["foo", "bar*"] ``` ```toml # tests with both "foo" and "bar*" tags extend-includes = ["fooANDbar*"] ``` corresponds to the `-i --include tag *` option of _robot_ ## extend-languages Type: `list[str | StringExpression] | None` Appends entries to the --language option. Activate localization. `lang` can be a name or a code of a built-in language, or a path or a module name of a custom language file. Examples: ```toml extend-languages = ["German", "Finnish"] ``` corresponds to the `--language lang *` option of _rebot_ ## extend-listeners Type: `dict[str, list[str | StringExpression]] | None` Appends entries to the --listener option. Class or module for monitoring test execution. Gets notifications e.g. when tests start and end. Arguments to the listener class can be given after the name using a colon or a semicolon as a separator. Examples: ```toml [extend-listeners] MyListener = [] "path/to/Listener.py" = ["arg1", "arg2"] ``` corresponds to the `--listener listener *` option of _rebot_ ## extend-metadata Type: `dict[str, str | StringExpression] | None` Appends entries to the --metadata option. Set metadata of the top level suite. Value can contain formatting and be read from a file similarly as --doc. Example: --metadata Version:1.2 Examples: ```toml [extend-metadata] Version = "1.2" # value can be read from a file (same rules as --doc) ReleaseNotes = "release_notes.txt" ``` corresponds to the `-M --metadata name:value *` option of _robot_ ## extend-parse-include Type: `list[str | StringExpression] | None` Appends entries to the --parseinclude option. Parse only files matching `pattern`. It can be: - a file name or pattern like `example.robot` or `*.robot` to parse all files matching that name, - a file path like `path/to/example.robot`, or - a directory path like `path/to/example` to parse all files in that directory, recursively. Examples: ```toml extend-parse-include = ["*.robot", "tests/**/*.robot"] ``` corresponds to the `-I --parseinclude pattern *` option of _robot_ ## extend-parsers Type: `dict[str, list[str | StringExpression]] | None` Appends entries to the --parser option. Custom parser class or module. Parser classes accept arguments the same way as with --listener. Examples: ```toml [extend-parsers] MyParser = [] "path/to/MyParser.py" = ["arg1", "arg2"] ``` corresponds to the `--parser parser *` option of _rebot_ ## extend-paths Type: `str | list[str] | None` Append extra entries to the paths argument. Examples: ```toml extend-paths = ["tests"] ``` ## extend-pre-rebot-modifiers Type: `dict[str, list[str | StringExpression]] | None` Appends entries to the --prerebotmodifier option. Class to programmatically modify the result model before creating reports and logs. Accepts arguments the same way as with --listener. Examples: ```toml [extend-pre-rebot-modifiers] "path/to/Modifier.py" = ["arg1"] ``` corresponds to the `--prerebotmodifier modifier *` option of _robot_ ## extend-pre-run-modifiers Type: `dict[str, list[str | StringExpression]] | None` Appends entries to the --prerunmodifier option. Class to programmatically modify the suite structure before execution. Accepts arguments the same way as with --listener. Examples: ```toml [extend-pre-run-modifiers] MyModifier = [] "path/to/Modifier.py" = ["arg1"] ``` corresponds to the `--prerunmodifier modifier *` option of _rebot_ ## extend-profiles Type: `dict[str, RobotProfile] | None` Extra execution profiles. ## extend-python-path Type: `list[str | StringExpression] | None` Appends entries to the --pythonpath option. Additional locations (directories, ZIPs) where to search libraries and other extensions when they are imported. Multiple paths can be given by separating them with a colon (`:`) or by using this option several times. Given path can also be a glob pattern matching multiple paths. Examples: ```toml extend-python-path = ["libs/", "/opt/libs", "libraries.zip"] ``` corresponds to the `-P --pythonpath path *` option of _robot_ ## extend-remove-keywords Type: `list[str | Literal['all', 'passed', 'for', 'wuks'] | NamePattern | TagPattern] | None` Appends entries to the --removekeywords option. Remove keyword data from the generated log file. Keywords containing warnings are not removed except in the `all` mode. **all:** remove data from all keywords **passed:** remove data only from keywords in passed test cases and suites **for:** remove passed iterations from FOR loops **while:** remove passed iterations from WHILE loops **wuks:** remove all but the last failing keyword inside `BuiltIn.Wait Until Keyword Succeeds` **name:\:** remove data from keywords that match the given pattern. The pattern is matched against the full name of the keyword (e.g. 'MyLib.Keyword', 'resource.Second Keyword'), is case, space, and underscore insensitive, and may contain `*`, `?` and `[]` wildcards. **tag:\:** remove data from keywords that match the given pattern. Tags are case and space insensitive and patterns can contain `*`, `?` and `[]` wildcards. Tags and patterns can also be combined together with `AND`, `OR`, and `NOT` operators. Examples: ```toml # match by keyword name extend-remove-keywords = ["name:Lib.HugeKw", "name:myresource.*"] ``` ```toml # match by tag pattern (same rules as --include) extend-remove-keywords = ["foo", "fooANDbar*"] ``` corresponds to the `--removekeywords all|passed|for|wuks|name:|tag: *` option of _robot_ ## extend-set-tag Type: `list[str | StringExpression] | None` Appends entries to the --settag option. Sets given tag(s) to all executed tests. Examples: ```toml extend-set-tag = ["my-suite-tag", "ci"] ``` corresponds to the `-G --settag tag *` option of _robot_ ## extend-skip Type: `list[str | StringExpression] | None` Appends entries to the --skip option. Tests having given tag will be skipped. Tag can be a pattern. Examples: ```toml extend-skip = ["bug-*", "wip"] ``` corresponds to the `--skip tag *` option of _rebot_ ## extend-skip-on-failure Type: `list[str | StringExpression] | None` Appends entries to the --skiponfailure option. Tests having given tag will be skipped if they fail. Tag can be a pattern Examples: ```toml extend-skip-on-failure = ["unstable"] ``` corresponds to the `--skiponfailure tag *` option of _rebot_ ## extend-suites Type: `list[str | StringExpression] | None` Appends entries to the --suite option. Select suites by name. When this option is used with --test, --include or --exclude, only tests in matching suites and also matching other filtering criteria are selected. Name can be a simple pattern similarly as with --test and it can contain parent name separated with a dot. For example, `-s X.Y` selects suite `Y` only if its parent is `X`. Examples: ```toml # match a suite by name or by parent.child path extend-suites = ["MySuite", "Tests.SubSuite"] ``` corresponds to the `-s --suite name *` option of _robot_ ## extend-tag-doc Type: `dict[str, str | StringExpression] | None` Appends entries to the --tagdoc option. Add documentation to tags matching the given pattern. Documentation is shown in `Test Details` and also as a tooltip in `Statistics by Tag`. Pattern can use `*`, `?` and `[]` as wildcards like --test. Examples: ```toml [extend-tag-doc] mytag = "Example" "owner-*" = "Original author" ``` corresponds to the `--tagdoc pattern:doc *` option of _robot_ ## extend-tag-stat-combine Type: `list[str | dict[str, str]] | None` Appends entries to the --tagstatcombine option. Create combined statistics based on tags. These statistics are added into `Statistics by Tag`. If the optional `name` is not given, name of the combined tag is got from the specified tags. Tags are matched using the same rules as with --include. Examples: ```toml extend-tag-stat-combine = ["requirement-*", { "tag1ANDtag2" = "My_name" }] ``` corresponds to the `--tagstatcombine tags:name *` option of _robot_ ## extend-tag-stat-exclude Type: `list[str | StringExpression] | None` Appends entries to the --tagstatexclude option. Exclude matching tags from `Statistics by Tag`. This option can be used with --tagstatinclude similarly as --exclude is used with --include. Examples: ```toml extend-tag-stat-exclude = ["bug-*"] ``` corresponds to the `--tagstatexclude tag *` option of _robot_ ## extend-tag-stat-include Type: `list[str | StringExpression] | None` Appends entries to the --tagstatinclude option. Include only matching tags in `Statistics by Tag` in log and report. By default all tags are shown. Given tag can be a pattern like with --include. Examples: ```toml extend-tag-stat-include = ["owner-*", "feature-*"] ``` corresponds to the `--tagstatinclude tag *` option of _robot_ ## extend-tag-stat-link Type: `dict[str, str | StringExpression] | None` Appends entries to the --tagstatlink option. Add external links into `Statistics by Tag`. Pattern can use `*`, `?` and `[]` as wildcards like --test. Characters matching to `*` and `?` wildcards can be used in link and title with syntax %N, where N is index of the match (starting from 1). Examples: ```toml [extend-tag-stat-link] mytag = "http://my.domain:Title" "bug-*" = "http://url/id=%1:Issue Tracker" ``` corresponds to the `--tagstatlink pattern:link:title *` option of _robot_ ## extend-tasks Type: `list[str | StringExpression] | None` Appends entries to the --task option. Alias to --test. Especially applicable with --rpa. Examples: ```toml extend-tasks = ["My Task", "Smoke*"] ``` corresponds to the `--task name *` option of _robot_ ## extend-tests Type: `list[str | StringExpression] | None` Appends entries to the --test option. Select tests by name or by long name containing also parent suite name like `Parent.Test`. Name is case and space insensitive and it can also be a simple pattern where `*` matches anything, `?` matches any single character, and `[chars]` matches one character in brackets. Examples: ```toml extend-tests = ["My Test", "Smoke*"] ``` corresponds to the `-t --test name *` option of _robot_ ## extend-variable-files Type: `list[str | StringExpression] | None` Appends entries to the --variablefile option. Python or YAML file file to read variables from. Possible arguments to the variable file can be given after the path using colon or semicolon as separator. Examples: ```toml extend-variable-files = ["path/vars.yaml", "environment.py:testing"] ``` corresponds to the `-V --variablefile path *` option of _rebot_ ## extend-variables Type: `dict[str, str | StringExpression] | None` Appends entries to the --variable option. Set variables in the test data. Only scalar variables with string value are supported and name is given without `${}`. See --variablefile for a more powerful variable setting mechanism. Examples: ```toml # sets ${name} to "Robot" [extend-variables] name = "Robot" ``` corresponds to the `-v --variable name:value *` option of _rebot_ ## extensions Type: `str | StringExpression | None` Parse only files with this extension when executing a directory. Has no effect when running individual files or when using resource files. If more than one extension is needed, separate them with a colon. Only `*.robot` files are parsed by default. Examples: ```toml extensions = "txt" ``` ```toml # parse multiple extensions (separator: colon) extensions = "robot:txt" ``` corresponds to the `-F --extension value` option of _robot_ ## flatten-keywords Type: `list[str | Literal['for', 'while', 'iteration'] | NamePattern | TagPattern] | None` Flattens matching keywords in the generated log file. Matching keywords get all log messages from their child keywords and children are discarded otherwise. **for:** flatten FOR loops fully **while:** flatten WHILE loops fully **iteration:** flatten FOR/WHILE loop iterations **foritem:** deprecated alias for `iteration` **name:\:** flatten matched keywords using same matching rules as with `--removekeywords name:` **tag:\:** flatten matched keywords using same matching rules as with `--removekeywords tag:` Examples: ```toml flatten-keywords = ["for", "name:Lib.HugeKw", "tag:flatten"] ``` corresponds to the `--flattenkeywords for|while|iteration|name:|tag: *` option of _robot_ ## includes Type: `list[str | StringExpression] | None` Select tests by tag. Similarly as name with --test, tag is case and space insensitive and it is possible to use patterns with `*`, `?` and `[]` as wildcards. Tags and patterns can also be combined together with `AND`, `OR`, and `NOT` operators. Examples: ```toml # match tests tagged "foo" or "bar*" includes = ["foo", "bar*"] ``` ```toml # tests with both "foo" and "bar*" tags includes = ["fooANDbar*"] ``` corresponds to the `-i --include tag *` option of _robot_ ## languages Type: `list[str | StringExpression] | None` Activate localization. `lang` can be a name or a code of a built-in language, or a path or a module name of a custom language file. Examples: ```toml languages = ["German", "Finnish"] ``` corresponds to the `--language lang *` option of _robot_ ## legacy-output Type: `bool | Flag | None` Create XML output file in format compatible with Robot Framework 6.x and earlier. Examples: ```toml legacy-output = true ``` corresponds to the `--legacyoutput` option of _robot_ ## libdoc Type: `LibDocProfile | None` Options to be passed to _libdoc_. ## libdoc.doc-format Type: `Literal['ROBOT', 'HTML', 'TEXT', 'REST'] | None` Specifies the source documentation format. Possible values are Robot Framework's documentation format, HTML, plain text, and reStructuredText. The default value can be specified in library source code and the initial default value is ROBOT. Examples: ```toml doc-format = "REST" ``` corresponds to the `-F --docformat ROBOT|HTML|TEXT|REST` option of _libdoc_ ## libdoc.extend-python-path Type: `list[str | StringExpression] | None` Appends entries to the --pythonpath option. Additional locations where to search for libraries and resources. Examples: ```toml extend-python-path = ["libs/", "/opt/libs", "libraries.zip"] ``` corresponds to the `-P --pythonpath path *` option of _libdoc_ ## libdoc.format Type: `Literal['HTML', 'XML', 'JSON', 'LIBSPEC'] | None` Specifies whether to generate an HTML output for humans or a machine readable spec file in XML or JSON format. The LIBSPEC format means XML spec with documentations converted to HTML. The default format is got from the output file extension. Examples: ```toml format = "HTML" ``` corresponds to the `-f --format HTML|XML|JSON|LIBSPEC` option of _libdoc_ ## libdoc.name Type: `str | StringExpression | None` Sets the name of the documented library or resource. Examples: ```toml name = "My Project" ``` corresponds to the `-n --name name` option of _libdoc_ ## libdoc.python-path Type: `list[str | StringExpression] | None` Additional locations where to search for libraries and resources. Examples: ```toml python-path = ["libs/", "/opt/libs", "libraries.zip"] ``` corresponds to the `-P --pythonpath path *` option of _libdoc_ ## libdoc.quiet Type: `bool | Flag | None` Do not print the path of the generated output file to the console. Examples: ```toml quiet = true ``` corresponds to the `--quiet` option of _libdoc_ ## libdoc.spec-doc-format Type: `Literal['RAW', 'HTML'] | None` Specifies the documentation format used with XML and JSON spec files. RAW means preserving the original documentation format and HTML means converting documentation to HTML. The default is RAW with XML spec files and HTML with JSON specs and when using the special LIBSPEC format. Examples: ```toml spec-doc-format = "HTML" ``` corresponds to the `-s --specdocformat RAW|HTML` option of _libdoc_ ## libdoc.theme Type: `Literal['DARK', 'LIGHT', 'NONE'] | None` Use dark or light HTML theme. If this option is not used, or the value is NONE, the theme is selected based on the browser color scheme. New in RF 6.0. Examples: ```toml theme = "DARK" ``` corresponds to the `--theme DARK|LIGHT|NONE` option of _libdoc_ ## listeners Type: `dict[str, list[str | StringExpression]] | None` Class or module for monitoring test execution. Gets notifications e.g. when tests start and end. Arguments to the listener class can be given after the name using a colon or a semicolon as a separator. Examples: ```toml [listeners] MyListener = [] "path/to/Listener.py" = ["arg1", "arg2"] ``` corresponds to the `--listener listener *` option of _robot_ ## log Type: `str | StringExpression | None` HTML log file. Can be disabled by giving a special value `NONE`. Default: log.html Examples: ```toml log = "mylog.html" ``` ```toml # disable log file generation log = "NONE" ``` corresponds to the `-l --log file` option of _robot_ ## log-level Type: `str | StringExpression | None` Threshold level for logging. Available levels: TRACE, DEBUG, INFO (default), WARN, NONE (no logging). Use syntax `LOGLEVEL:DEFAULT` to define the default visible log level in log files. Examples: ```toml log-level = "DEBUG" ``` ```toml # explicit visible level (default: INFO) log-level = "DEBUG:INFO" ``` corresponds to the `-L --loglevel level` option of _robot_ ## log-title Type: `str | StringExpression | None` Title for the generated log file. The default title is ` Log`. Examples: ```toml log-title = "My Project Log" ``` corresponds to the `--logtitle title` option of _robot_ ## max-assign-length Type: `int | None` Maximum number of characters to show in log when variables are assigned. Zero or negative values can be used to avoid showing assigned values at all. Default is 200. Examples: ```toml max-assign-length = 200 ``` corresponds to the `--maxassignlength characters` option of _robot_ ## max-error-lines Type: `int | None` Maximum number of error message lines to show in report when tests fail. Default is 40, minimum is 10 and `NONE` can be used to show the full message. Examples: ```toml max-error-lines = 40 ``` corresponds to the `--maxerrorlines lines` option of _robot_ ## metadata Type: `dict[str, str | StringExpression] | None` Set metadata of the top level suite. Value can contain formatting and be read from a file similarly as --doc. Example: --metadata Version:1.2 Examples: ```toml [metadata] Version = "1.2" # value can be read from a file (same rules as --doc) ReleaseNotes = "release_notes.txt" ``` corresponds to the `-M --metadata name:value *` option of _robot_ ## name Type: `str | StringExpression | None` Set the name of the top level suite. By default the name is created based on the executed file or directory. Examples: ```toml name = "My Project" ``` corresponds to the `-N --name name` option of _robot_ ## no-status-rc Type: `bool | Flag | None` Sets the return code to zero regardless of failures in test cases. Error codes are returned normally. Examples: ```toml # always exit 0 regardless of failed tests no-status-rc = true ``` corresponds to the `--nostatusrc` option of _robot_ ## output Type: `str | StringExpression | None` XML output file. Given path, similarly as paths given to --log, --report, --xunit, and --debugfile, is relative to --outputdir unless given as an absolute path. Other output files are created based on XML output files after the test execution and XML outputs can also be further processed with Rebot tool. Can be disabled by giving a special value `NONE`. **Default:** output.xml Examples: ```toml output = "output.xml" ``` corresponds to the `-o --output file` option of _robot_ ## output-dir Type: `str | StringExpression | None` Where to create output files. The default is the directory where tests are run from and the given path is considered relative to that unless it is absolute. Examples: ```toml output-dir = "results" ``` corresponds to the `-d --outputdir dir` option of _robot_ ## parse-include Type: `list[str | StringExpression] | None` Parse only files matching `pattern`. It can be: - a file name or pattern like `example.robot` or `*.robot` to parse all files matching that name, - a file path like `path/to/example.robot`, or - a directory path like `path/to/example` to parse all files in that directory, recursively. Examples: ```toml parse-include = ["*.robot", "tests/**/*.robot"] ``` corresponds to the `-I --parseinclude pattern *` option of _robot_ ## parsers Type: `dict[str, list[str | StringExpression]] | None` Custom parser class or module. Parser classes accept arguments the same way as with --listener. Examples: ```toml [parsers] MyParser = [] "path/to/MyParser.py" = ["arg1", "arg2"] ``` corresponds to the `--parser parser *` option of _robot_ ## paths Type: `str | list[str] | None` Specifies the paths where robot/robotcode should discover tests. If no paths are given at the command line this value is used. Examples: ```toml paths = ["tests"] ``` Corresponds to the `paths` argument of __robot__. ## pre-rebot-modifiers Type: `dict[str, list[str | StringExpression]] | None` Class to programmatically modify the result model before creating reports and logs. Accepts arguments the same way as with --listener. Examples: ```toml [pre-rebot-modifiers] "path/to/Modifier.py" = ["arg1"] ``` corresponds to the `--prerebotmodifier modifier *` option of _robot_ ## pre-run-modifiers Type: `dict[str, list[str | StringExpression]] | None` Class to programmatically modify the suite structure before execution. Accepts arguments the same way as with --listener. Examples: ```toml [pre-run-modifiers] MyModifier = [] "path/to/Modifier.py" = ["arg1"] ``` corresponds to the `--prerunmodifier modifier *` option of _robot_ ## profiles Type: `dict[str, RobotProfile] | None` Execution profiles. ## python-path Type: `list[str | StringExpression] | None` Additional locations (directories, ZIPs) where to search libraries and other extensions when they are imported. Multiple paths can be given by separating them with a colon (`:`) or by using this option several times. Given path can also be a glob pattern matching multiple paths. Examples: ```toml python-path = ["libs/", "/opt/libs", "libraries.zip"] ``` corresponds to the `-P --pythonpath path *` option of _robot_ ## quiet Type: `bool | Flag | None` Shortcut for `--console quiet`. Examples: ```toml quiet = true ``` corresponds to the `--quiet` option of _robot_ ## randomize Type: `str | Literal['all', 'suites', 'tests', 'none'] | None` Randomizes the test execution order. **all:** randomizes both suites and tests **suites:** randomizes suites **tests:** randomizes tests **none:** no randomization (default) Use syntax `VALUE:SEED` to give a custom random seed. The seed must be an integer. Examples: ```toml randomize = "all" ``` ```toml # randomize tests with a fixed seed randomize = "tests:1234" ``` corresponds to the `--randomize all|suites|tests|none` option of _robot_ ## re-run-failed Type: `str | StringExpression | None` Select failed tests from an earlier output file to be re-executed. Equivalent to selecting same tests individually using --test. Examples: ```toml re-run-failed = "output.xml" ``` corresponds to the `-R --rerunfailed output` option of _robot_ ## re-run-failed-suites Type: `str | StringExpression | None` Select failed suites from an earlier output file to be re-executed. Examples: ```toml re-run-failed-suites = "output.xml" ``` corresponds to the `-S --rerunfailedsuites output` option of _robot_ ## rebot Type: `RebotProfile | None` Options to be passed to _rebot_. ## rebot.console-colors Type: `Literal['auto', 'on', 'ansi', 'off'] | None` Use colors on console output or not. **auto:** use colors when output not redirected (default) **on:** always use colors **ansi:** like `on` but use ANSI colors also on Windows **off:** disable colors altogether Examples: ```toml console-colors = "on" ``` corresponds to the `-C --consolecolors auto|on|ansi|off` option of _robot_ ## rebot.console-links Type: `Literal['auto', 'off'] | None` Control making paths to results files hyperlinks. **auto:** use links when colors are enabled (default) **off:** disable links unconditionally Examples: ```toml console-links = "off" ``` corresponds to the `--consolelinks auto|off` option of _robot_ ## rebot.doc Type: `str | StringExpression | None` Set the documentation of the top level suite. Simple formatting is supported (e.g. *bold*). If the documentation contains spaces, it must be quoted. If the value is path to an existing file, actual documentation is read from that file. Examples: ```toml doc = "Very *good* example" ``` ```toml # read documentation from a file doc = "doc_from_file.txt" ``` corresponds to the `-D --doc documentation` option of _robot_ ## rebot.end-time Type: `str | StringExpression | None` Same as --starttime but for end time. If both options are used, elapsed time of the suite is calculated based on them. For combined suites, it is otherwise calculated by adding elapsed times of the combined suites together. Examples: ```toml end-time = "2024-12-15 14:35:42.123" ``` corresponds to the `--endtime timestamp` option of _rebot_ ## rebot.excludes Type: `list[str | StringExpression] | None` Select test cases not to run by tag. These tests are not run even if included with --include. Tags are matched using same rules as with --include. Examples: ```toml excludes = ["smoke", "wip*"] ``` corresponds to the `-e --exclude tag *` option of _robot_ ## rebot.expand-keywords Type: `list[str | NamePattern | TagPattern] | None` Matching keywords will be automatically expanded in the log file. Matching against keyword name or tags work using same rules as with --removekeywords. Examples: ```toml expand-keywords = ["name:BuiltIn.Log", "tag:expand"] ``` corresponds to the `--expandkeywords name:|tag: *` option of _robot_ ## rebot.extend-excludes Type: `list[str | StringExpression] | None` Appends entries to the --exclude option. Select test cases not to run by tag. These tests are not run even if included with --include. Tags are matched using same rules as with --include. Examples: ```toml extend-excludes = ["smoke", "wip*"] ``` corresponds to the `-e --exclude tag *` option of _robot_ ## rebot.extend-expand-keywords Type: `list[str | NamePattern | TagPattern] | None` Appends entries to the --expandkeywords option. Matching keywords will be automatically expanded in the log file. Matching against keyword name or tags work using same rules as with --removekeywords. Examples: ```toml extend-expand-keywords = ["name:BuiltIn.Log", "tag:expand"] ``` corresponds to the `--expandkeywords name:|tag: *` option of _robot_ ## rebot.extend-flatten-keywords Type: `list[str | Literal['for', 'while', 'iteration'] | NamePattern | TagPattern] | None` Appends entries to the --flattenkeywords option. Flattens matching keywords in the generated log file. Matching keywords get all log messages from their child keywords and children are discarded otherwise. **for:** flatten FOR loops fully **while:** flatten WHILE loops fully **iteration:** flatten FOR/WHILE loop iterations **foritem:** deprecated alias for `iteration` **name:\:** flatten matched keywords using same matching rules as with `--removekeywords name:` **tag:\:** flatten matched keywords using same matching rules as with `--removekeywords tag:` Examples: ```toml extend-flatten-keywords = ["for", "name:Lib.HugeKw", "tag:flatten"] ``` corresponds to the `--flattenkeywords for|while|iteration|name:|tag: *` option of _robot_ ## rebot.extend-includes Type: `list[str | StringExpression] | None` Appends entries to the --include option. Select tests by tag. Similarly as name with --test, tag is case and space insensitive and it is possible to use patterns with `*`, `?` and `[]` as wildcards. Tags and patterns can also be combined together with `AND`, `OR`, and `NOT` operators. Examples: ```toml # match tests tagged "foo" or "bar*" extend-includes = ["foo", "bar*"] ``` ```toml # tests with both "foo" and "bar*" tags extend-includes = ["fooANDbar*"] ``` corresponds to the `-i --include tag *` option of _robot_ ## rebot.extend-metadata Type: `dict[str, str | StringExpression] | None` Appends entries to the --metadata option. Set metadata of the top level suite. Value can contain formatting and be read from a file similarly as --doc. Example: --metadata Version:1.2 Examples: ```toml [extend-metadata] Version = "1.2" # value can be read from a file (same rules as --doc) ReleaseNotes = "release_notes.txt" ``` corresponds to the `-M --metadata name:value *` option of _robot_ ## rebot.extend-parse-include Type: `list[str | StringExpression] | None` Appends entries to the --parseinclude option. Parse only files matching `pattern`. It can be: - a file name or pattern like `example.robot` or `*.robot` to parse all files matching that name, - a file path like `path/to/example.robot`, or - a directory path like `path/to/example` to parse all files in that directory, recursively. Examples: ```toml extend-parse-include = ["*.robot", "tests/**/*.robot"] ``` corresponds to the `-I --parseinclude pattern *` option of _robot_ ## rebot.extend-pre-rebot-modifiers Type: `dict[str, list[str | StringExpression]] | None` Appends entries to the --prerebotmodifier option. Class to programmatically modify the result model before creating reports and logs. Accepts arguments the same way as with --listener. Examples: ```toml [extend-pre-rebot-modifiers] "path/to/Modifier.py" = ["arg1"] ``` corresponds to the `--prerebotmodifier modifier *` option of _robot_ ## rebot.extend-python-path Type: `list[str | StringExpression] | None` Appends entries to the --pythonpath option. Additional locations (directories, ZIPs) where to search libraries and other extensions when they are imported. Multiple paths can be given by separating them with a colon (`:`) or by using this option several times. Given path can also be a glob pattern matching multiple paths. Examples: ```toml extend-python-path = ["libs/", "/opt/libs", "libraries.zip"] ``` corresponds to the `-P --pythonpath path *` option of _robot_ ## rebot.extend-remove-keywords Type: `list[str | Literal['all', 'passed', 'for', 'wuks'] | NamePattern | TagPattern] | None` Appends entries to the --removekeywords option. Remove keyword data from the generated log file. Keywords containing warnings are not removed except in the `all` mode. **all:** remove data from all keywords **passed:** remove data only from keywords in passed test cases and suites **for:** remove passed iterations from FOR loops **while:** remove passed iterations from WHILE loops **wuks:** remove all but the last failing keyword inside `BuiltIn.Wait Until Keyword Succeeds` **name:\:** remove data from keywords that match the given pattern. The pattern is matched against the full name of the keyword (e.g. 'MyLib.Keyword', 'resource.Second Keyword'), is case, space, and underscore insensitive, and may contain `*`, `?` and `[]` wildcards. **tag:\:** remove data from keywords that match the given pattern. Tags are case and space insensitive and patterns can contain `*`, `?` and `[]` wildcards. Tags and patterns can also be combined together with `AND`, `OR`, and `NOT` operators. Examples: ```toml # match by keyword name extend-remove-keywords = ["name:Lib.HugeKw", "name:myresource.*"] ``` ```toml # match by tag pattern (same rules as --include) extend-remove-keywords = ["foo", "fooANDbar*"] ``` corresponds to the `--removekeywords all|passed|for|wuks|name:|tag: *` option of _robot_ ## rebot.extend-set-tag Type: `list[str | StringExpression] | None` Appends entries to the --settag option. Sets given tag(s) to all executed tests. Examples: ```toml extend-set-tag = ["my-suite-tag", "ci"] ``` corresponds to the `-G --settag tag *` option of _robot_ ## rebot.extend-suites Type: `list[str | StringExpression] | None` Appends entries to the --suite option. Select suites by name. When this option is used with --test, --include or --exclude, only tests in matching suites and also matching other filtering criteria are selected. Name can be a simple pattern similarly as with --test and it can contain parent name separated with a dot. For example, `-s X.Y` selects suite `Y` only if its parent is `X`. Examples: ```toml # match a suite by name or by parent.child path extend-suites = ["MySuite", "Tests.SubSuite"] ``` corresponds to the `-s --suite name *` option of _robot_ ## rebot.extend-tag-doc Type: `dict[str, str | StringExpression] | None` Appends entries to the --tagdoc option. Add documentation to tags matching the given pattern. Documentation is shown in `Test Details` and also as a tooltip in `Statistics by Tag`. Pattern can use `*`, `?` and `[]` as wildcards like --test. Examples: ```toml [extend-tag-doc] mytag = "Example" "owner-*" = "Original author" ``` corresponds to the `--tagdoc pattern:doc *` option of _robot_ ## rebot.extend-tag-stat-combine Type: `list[str | dict[str, str]] | None` Appends entries to the --tagstatcombine option. Create combined statistics based on tags. These statistics are added into `Statistics by Tag`. If the optional `name` is not given, name of the combined tag is got from the specified tags. Tags are matched using the same rules as with --include. Examples: ```toml extend-tag-stat-combine = ["requirement-*", { "tag1ANDtag2" = "My_name" }] ``` corresponds to the `--tagstatcombine tags:name *` option of _robot_ ## rebot.extend-tag-stat-exclude Type: `list[str | StringExpression] | None` Appends entries to the --tagstatexclude option. Exclude matching tags from `Statistics by Tag`. This option can be used with --tagstatinclude similarly as --exclude is used with --include. Examples: ```toml extend-tag-stat-exclude = ["bug-*"] ``` corresponds to the `--tagstatexclude tag *` option of _robot_ ## rebot.extend-tag-stat-include Type: `list[str | StringExpression] | None` Appends entries to the --tagstatinclude option. Include only matching tags in `Statistics by Tag` in log and report. By default all tags are shown. Given tag can be a pattern like with --include. Examples: ```toml extend-tag-stat-include = ["owner-*", "feature-*"] ``` corresponds to the `--tagstatinclude tag *` option of _robot_ ## rebot.extend-tag-stat-link Type: `dict[str, str | StringExpression] | None` Appends entries to the --tagstatlink option. Add external links into `Statistics by Tag`. Pattern can use `*`, `?` and `[]` as wildcards like --test. Characters matching to `*` and `?` wildcards can be used in link and title with syntax %N, where N is index of the match (starting from 1). Examples: ```toml [extend-tag-stat-link] mytag = "http://my.domain:Title" "bug-*" = "http://url/id=%1:Issue Tracker" ``` corresponds to the `--tagstatlink pattern:link:title *` option of _robot_ ## rebot.extend-tasks Type: `list[str | StringExpression] | None` Appends entries to the --task option. Alias to --test. Especially applicable with --rpa. Examples: ```toml extend-tasks = ["My Task", "Smoke*"] ``` corresponds to the `--task name *` option of _robot_ ## rebot.extend-tests Type: `list[str | StringExpression] | None` Appends entries to the --test option. Select tests by name or by long name containing also parent suite name like `Parent.Test`. Name is case and space insensitive and it can also be a simple pattern where `*` matches anything, `?` matches any single character, and `[chars]` matches one character in brackets. Examples: ```toml extend-tests = ["My Test", "Smoke*"] ``` corresponds to the `-t --test name *` option of _robot_ ## rebot.flatten-keywords Type: `list[str | Literal['for', 'while', 'iteration'] | NamePattern | TagPattern] | None` Flattens matching keywords in the generated log file. Matching keywords get all log messages from their child keywords and children are discarded otherwise. **for:** flatten FOR loops fully **while:** flatten WHILE loops fully **iteration:** flatten FOR/WHILE loop iterations **foritem:** deprecated alias for `iteration` **name:\:** flatten matched keywords using same matching rules as with `--removekeywords name:` **tag:\:** flatten matched keywords using same matching rules as with `--removekeywords tag:` Examples: ```toml flatten-keywords = ["for", "name:Lib.HugeKw", "tag:flatten"] ``` corresponds to the `--flattenkeywords for|while|iteration|name:|tag: *` option of _robot_ ## rebot.includes Type: `list[str | StringExpression] | None` Select tests by tag. Similarly as name with --test, tag is case and space insensitive and it is possible to use patterns with `*`, `?` and `[]` as wildcards. Tags and patterns can also be combined together with `AND`, `OR`, and `NOT` operators. Examples: ```toml # match tests tagged "foo" or "bar*" includes = ["foo", "bar*"] ``` ```toml # tests with both "foo" and "bar*" tags includes = ["fooANDbar*"] ``` corresponds to the `-i --include tag *` option of _robot_ ## rebot.legacy-output Type: `bool | Flag | None` Create XML output file in format compatible with Robot Framework 6.x and earlier. Examples: ```toml legacy-output = true ``` corresponds to the `--legacyoutput` option of _robot_ ## rebot.log Type: `str | StringExpression | None` HTML log file. Can be disabled by giving a special value `NONE`. Default: log.html Examples: ```toml log = "mylog.html" ``` ```toml # disable log file generation log = "NONE" ``` corresponds to the `-l --log file` option of _robot_ ## rebot.log-level Type: `str | StringExpression | None` Threshold for selecting messages. Available levels: TRACE (default), DEBUG, INFO, WARN, NONE (no msgs). Use syntax `LOGLEVEL:DEFAULT` to define the default visible log level in log files. Examples: ```toml log-level = "DEBUG" ``` ```toml # explicit visible level (default: INFO) log-level = "DEBUG:INFO" ``` corresponds to the `-L --loglevel level` option of _rebot_ ## rebot.log-title Type: `str | StringExpression | None` Title for the generated log file. The default title is ` Log`. Examples: ```toml log-title = "My Project Log" ``` corresponds to the `--logtitle title` option of _robot_ ## rebot.merge Type: `bool | Flag | None` When combining results, merge outputs together instead of putting them under a new top level suite. **Example:** rebot --merge orig.xml rerun.xml Examples: ```toml merge = true ``` corresponds to the `-R --merge` option of _rebot_ ## rebot.metadata Type: `dict[str, str | StringExpression] | None` Set metadata of the top level suite. Value can contain formatting and be read from a file similarly as --doc. Example: --metadata Version:1.2 Examples: ```toml [metadata] Version = "1.2" # value can be read from a file (same rules as --doc) ReleaseNotes = "release_notes.txt" ``` corresponds to the `-M --metadata name:value *` option of _robot_ ## rebot.name Type: `str | StringExpression | None` Set the name of the top level suite. By default the name is created based on the executed file or directory. Examples: ```toml name = "My Project" ``` corresponds to the `-N --name name` option of _robot_ ## rebot.no-status-rc Type: `bool | Flag | None` Sets the return code to zero regardless of failures in test cases. Error codes are returned normally. Examples: ```toml # always exit 0 regardless of failed tests no-status-rc = true ``` corresponds to the `--nostatusrc` option of _robot_ ## rebot.output Type: `str | StringExpression | None` XML output file. Not created unless this option is specified. Given path, similarly as paths given to --log, --report and --xunit, is relative to --outputdir unless given as an absolute path. Examples: ```toml output = "output.xml" ``` corresponds to the `-o --output file` option of _rebot_ ## rebot.output-dir Type: `str | StringExpression | None` Where to create output files. The default is the directory where tests are run from and the given path is considered relative to that unless it is absolute. Examples: ```toml output-dir = "results" ``` corresponds to the `-d --outputdir dir` option of _robot_ ## rebot.parse-include Type: `list[str | StringExpression] | None` Parse only files matching `pattern`. It can be: - a file name or pattern like `example.robot` or `*.robot` to parse all files matching that name, - a file path like `path/to/example.robot`, or - a directory path like `path/to/example` to parse all files in that directory, recursively. Examples: ```toml parse-include = ["*.robot", "tests/**/*.robot"] ``` corresponds to the `-I --parseinclude pattern *` option of _robot_ ## rebot.pre-rebot-modifiers Type: `dict[str, list[str | StringExpression]] | None` Class to programmatically modify the result model before creating reports and logs. Accepts arguments the same way as with --listener. Examples: ```toml [pre-rebot-modifiers] "path/to/Modifier.py" = ["arg1"] ``` corresponds to the `--prerebotmodifier modifier *` option of _robot_ ## rebot.process-empty-suite Type: `bool | Flag | None` Processes output also if the top level suite is empty. Useful e.g. with --include/--exclude when it is not an error that there are no matches. Examples: ```toml process-empty-suite = true ``` corresponds to the `--processemptysuite` option of _rebot_ ## rebot.python-path Type: `list[str | StringExpression] | None` Additional locations (directories, ZIPs) where to search libraries and other extensions when they are imported. Multiple paths can be given by separating them with a colon (`:`) or by using this option several times. Given path can also be a glob pattern matching multiple paths. Examples: ```toml python-path = ["libs/", "/opt/libs", "libraries.zip"] ``` corresponds to the `-P --pythonpath path *` option of _robot_ ## rebot.remove-keywords Type: `list[str | Literal['all', 'passed', 'for', 'wuks'] | NamePattern | TagPattern] | None` Remove keyword data from the generated log file. Keywords containing warnings are not removed except in the `all` mode. **all:** remove data from all keywords **passed:** remove data only from keywords in passed test cases and suites **for:** remove passed iterations from FOR loops **while:** remove passed iterations from WHILE loops **wuks:** remove all but the last failing keyword inside `BuiltIn.Wait Until Keyword Succeeds` **name:\:** remove data from keywords that match the given pattern. The pattern is matched against the full name of the keyword (e.g. 'MyLib.Keyword', 'resource.Second Keyword'), is case, space, and underscore insensitive, and may contain `*`, `?` and `[]` wildcards. **tag:\:** remove data from keywords that match the given pattern. Tags are case and space insensitive and patterns can contain `*`, `?` and `[]` wildcards. Tags and patterns can also be combined together with `AND`, `OR`, and `NOT` operators. Examples: ```toml # match by keyword name remove-keywords = ["name:Lib.HugeKw", "name:myresource.*"] ``` ```toml # match by tag pattern (same rules as --include) remove-keywords = ["foo", "fooANDbar*"] ``` corresponds to the `--removekeywords all|passed|for|wuks|name:|tag: *` option of _robot_ ## rebot.report Type: `str | StringExpression | None` HTML report file. Can be disabled with `NONE` similarly as --log. Default: report.html Examples: ```toml report = "report.html" ``` corresponds to the `-r --report file` option of _robot_ ## rebot.report-background Type: `str | StringExpression | None` Background colors to use in the report file. Given in format `passed:failed:skipped` where the `:skipped` part can be omitted. Both color names and codes work. Examples: ```toml # pass:fail:skip colours report-background = "green:red:yellow" ``` ```toml # pass:fail (skip uses the fail colour) report-background = "#00E:#E00" ``` corresponds to the `--reportbackground colors` option of _robot_ ## rebot.report-title Type: `str | StringExpression | None` Title for the generated report file. The default title is ` Report`. Examples: ```toml report-title = "My Project Report" ``` corresponds to the `--reporttitle title` option of _robot_ ## rebot.rpa Type: `bool | Flag | None` Turn on the generic automation mode. Mainly affects terminology so that "test" is replaced with "task" in logs and reports. By default the mode is got from test/task header in data files. Examples: ```toml rpa = true ``` corresponds to the `--rpa` option of _robot_ ## rebot.set-tag Type: `list[str | StringExpression] | None` Sets given tag(s) to all executed tests. Examples: ```toml set-tag = ["my-suite-tag", "ci"] ``` corresponds to the `-G --settag tag *` option of _robot_ ## rebot.split-log Type: `bool | Flag | None` Split the log file into smaller pieces that open in browsers transparently. Examples: ```toml split-log = true ``` corresponds to the `--splitlog` option of _robot_ ## rebot.start-time Type: `str | StringExpression | None` Set execution start time. Timestamp must be given in format `2007-10-01 15:12:42.268` where all separators are optional (e.g. `20071001151242268` is ok too) and parts from milliseconds to hours can be omitted if they are zero (e.g. `2007-10-01`). This can be used to override start time of a single suite or to set start time for a combined suite, which would otherwise be `N/A`. Examples: ```toml start-time = "2024-12-15 14:30:00.000" ``` corresponds to the `--starttime timestamp` option of _rebot_ ## rebot.suite-stat-level Type: `int | None` How many levels to show in `Statistics by Suite` in log and report. By default all suite levels are shown. Example: --suitestatlevel 3 Examples: ```toml suite-stat-level = 2 ``` corresponds to the `--suitestatlevel level` option of _robot_ ## rebot.suites Type: `list[str | StringExpression] | None` Select suites by name. When this option is used with --test, --include or --exclude, only tests in matching suites and also matching other filtering criteria are selected. Name can be a simple pattern similarly as with --test and it can contain parent name separated with a dot. For example, `-s X.Y` selects suite `Y` only if its parent is `X`. Examples: ```toml # match a suite by name or by parent.child path suites = ["MySuite", "Tests.SubSuite"] ``` corresponds to the `-s --suite name *` option of _robot_ ## rebot.tag-doc Type: `dict[str, str | StringExpression] | None` Add documentation to tags matching the given pattern. Documentation is shown in `Test Details` and also as a tooltip in `Statistics by Tag`. Pattern can use `*`, `?` and `[]` as wildcards like --test. Examples: ```toml [tag-doc] mytag = "Example" "owner-*" = "Original author" ``` corresponds to the `--tagdoc pattern:doc *` option of _robot_ ## rebot.tag-stat-combine Type: `list[str | dict[str, str]] | None` Create combined statistics based on tags. These statistics are added into `Statistics by Tag`. If the optional `name` is not given, name of the combined tag is got from the specified tags. Tags are matched using the same rules as with --include. Examples: ```toml tag-stat-combine = ["requirement-*", { "tag1ANDtag2" = "My_name" }] ``` corresponds to the `--tagstatcombine tags:name *` option of _robot_ ## rebot.tag-stat-exclude Type: `list[str | StringExpression] | None` Exclude matching tags from `Statistics by Tag`. This option can be used with --tagstatinclude similarly as --exclude is used with --include. Examples: ```toml tag-stat-exclude = ["bug-*"] ``` corresponds to the `--tagstatexclude tag *` option of _robot_ ## rebot.tag-stat-include Type: `list[str | StringExpression] | None` Include only matching tags in `Statistics by Tag` in log and report. By default all tags are shown. Given tag can be a pattern like with --include. Examples: ```toml tag-stat-include = ["owner-*", "feature-*"] ``` corresponds to the `--tagstatinclude tag *` option of _robot_ ## rebot.tag-stat-link Type: `dict[str, str | StringExpression] | None` Add external links into `Statistics by Tag`. Pattern can use `*`, `?` and `[]` as wildcards like --test. Characters matching to `*` and `?` wildcards can be used in link and title with syntax %N, where N is index of the match (starting from 1). Examples: ```toml [tag-stat-link] mytag = "http://my.domain:Title" "bug-*" = "http://url/id=%1:Issue Tracker" ``` corresponds to the `--tagstatlink pattern:link:title *` option of _robot_ ## rebot.tasks Type: `list[str | StringExpression] | None` Alias to --test. Especially applicable with --rpa. Examples: ```toml tasks = ["My Task", "Smoke*"] ``` corresponds to the `--task name *` option of _robot_ ## rebot.tests Type: `list[str | StringExpression] | None` Select tests by name or by long name containing also parent suite name like `Parent.Test`. Name is case and space insensitive and it can also be a simple pattern where `*` matches anything, `?` matches any single character, and `[chars]` matches one character in brackets. Examples: ```toml tests = ["My Test", "Smoke*"] ``` corresponds to the `-t --test name *` option of _robot_ ## rebot.timestamp-outputs Type: `bool | Flag | None` When this option is used, timestamp in a format `YYYYMMDD-hhmmss` is added to all generated output files between their basename and extension. For example `-T -o output.xml -r report.html -l none` creates files like `output-20070503-154410.xml` and `report-20070503-154410.html`. Examples: ```toml timestamp-outputs = true ``` corresponds to the `-T --timestampoutputs` option of _robot_ ## rebot.xunit Type: `str | StringExpression | None` xUnit compatible result file. Not created unless this option is specified. Examples: ```toml xunit = "xunit.xml" ``` corresponds to the `-x --xunit file` option of _robot_ ## remove-keywords Type: `list[str | Literal['all', 'passed', 'for', 'wuks'] | NamePattern | TagPattern] | None` Remove keyword data from the generated log file. Keywords containing warnings are not removed except in the `all` mode. **all:** remove data from all keywords **passed:** remove data only from keywords in passed test cases and suites **for:** remove passed iterations from FOR loops **while:** remove passed iterations from WHILE loops **wuks:** remove all but the last failing keyword inside `BuiltIn.Wait Until Keyword Succeeds` **name:\:** remove data from keywords that match the given pattern. The pattern is matched against the full name of the keyword (e.g. 'MyLib.Keyword', 'resource.Second Keyword'), is case, space, and underscore insensitive, and may contain `*`, `?` and `[]` wildcards. **tag:\:** remove data from keywords that match the given pattern. Tags are case and space insensitive and patterns can contain `*`, `?` and `[]` wildcards. Tags and patterns can also be combined together with `AND`, `OR`, and `NOT` operators. Examples: ```toml # match by keyword name remove-keywords = ["name:Lib.HugeKw", "name:myresource.*"] ``` ```toml # match by tag pattern (same rules as --include) remove-keywords = ["foo", "fooANDbar*"] ``` corresponds to the `--removekeywords all|passed|for|wuks|name:|tag: *` option of _robot_ ## report Type: `str | StringExpression | None` HTML report file. Can be disabled with `NONE` similarly as --log. Default: report.html Examples: ```toml report = "report.html" ``` corresponds to the `-r --report file` option of _robot_ ## report-background Type: `str | StringExpression | None` Background colors to use in the report file. Given in format `passed:failed:skipped` where the `:skipped` part can be omitted. Both color names and codes work. Examples: ```toml # pass:fail:skip colours report-background = "green:red:yellow" ``` ```toml # pass:fail (skip uses the fail colour) report-background = "#00E:#E00" ``` corresponds to the `--reportbackground colors` option of _robot_ ## report-title Type: `str | StringExpression | None` Title for the generated report file. The default title is ` Report`. Examples: ```toml report-title = "My Project Report" ``` corresponds to the `--reporttitle title` option of _robot_ ## rpa Type: `bool | Flag | None` Turn on the generic automation mode. Mainly affects terminology so that "test" is replaced with "task" in logs and reports. By default the mode is got from test/task header in data files. Examples: ```toml rpa = true ``` corresponds to the `--rpa` option of _robot_ ## run-empty-suite Type: `bool | Flag | None` Executes suite even if it contains no tests. Useful e.g. with --include/--exclude when it is not an error that no test matches the condition. Examples: ```toml run-empty-suite = true ``` corresponds to the `--runemptysuite` option of _robot_ ## set-tag Type: `list[str | StringExpression] | None` Sets given tag(s) to all executed tests. Examples: ```toml set-tag = ["my-suite-tag", "ci"] ``` corresponds to the `-G --settag tag *` option of _robot_ ## skip Type: `list[str | StringExpression] | None` Tests having given tag will be skipped. Tag can be a pattern. Examples: ```toml skip = ["bug-*", "wip"] ``` corresponds to the `--skip tag *` option of _robot_ ## skip-on-failure Type: `list[str | StringExpression] | None` Tests having given tag will be skipped if they fail. Tag can be a pattern Examples: ```toml skip-on-failure = ["unstable"] ``` corresponds to the `--skiponfailure tag *` option of _robot_ ## skip-teardown-on-exit Type: `bool | Flag | None` Causes teardowns to be skipped if test execution is stopped prematurely. Examples: ```toml skip-teardown-on-exit = true ``` corresponds to the `--skipteardownonexit` option of _robot_ ## split-log Type: `bool | Flag | None` Split the log file into smaller pieces that open in browsers transparently. Examples: ```toml split-log = true ``` corresponds to the `--splitlog` option of _robot_ ## suite-stat-level Type: `int | None` How many levels to show in `Statistics by Suite` in log and report. By default all suite levels are shown. Example: --suitestatlevel 3 Examples: ```toml suite-stat-level = 2 ``` corresponds to the `--suitestatlevel level` option of _robot_ ## suites Type: `list[str | StringExpression] | None` Select suites by name. When this option is used with --test, --include or --exclude, only tests in matching suites and also matching other filtering criteria are selected. Name can be a simple pattern similarly as with --test and it can contain parent name separated with a dot. For example, `-s X.Y` selects suite `Y` only if its parent is `X`. Examples: ```toml # match a suite by name or by parent.child path suites = ["MySuite", "Tests.SubSuite"] ``` corresponds to the `-s --suite name *` option of _robot_ ## tag-doc Type: `dict[str, str | StringExpression] | None` Add documentation to tags matching the given pattern. Documentation is shown in `Test Details` and also as a tooltip in `Statistics by Tag`. Pattern can use `*`, `?` and `[]` as wildcards like --test. Examples: ```toml [tag-doc] mytag = "Example" "owner-*" = "Original author" ``` corresponds to the `--tagdoc pattern:doc *` option of _robot_ ## tag-stat-combine Type: `list[str | dict[str, str]] | None` Create combined statistics based on tags. These statistics are added into `Statistics by Tag`. If the optional `name` is not given, name of the combined tag is got from the specified tags. Tags are matched using the same rules as with --include. Examples: ```toml tag-stat-combine = ["requirement-*", { "tag1ANDtag2" = "My_name" }] ``` corresponds to the `--tagstatcombine tags:name *` option of _robot_ ## tag-stat-exclude Type: `list[str | StringExpression] | None` Exclude matching tags from `Statistics by Tag`. This option can be used with --tagstatinclude similarly as --exclude is used with --include. Examples: ```toml tag-stat-exclude = ["bug-*"] ``` corresponds to the `--tagstatexclude tag *` option of _robot_ ## tag-stat-include Type: `list[str | StringExpression] | None` Include only matching tags in `Statistics by Tag` in log and report. By default all tags are shown. Given tag can be a pattern like with --include. Examples: ```toml tag-stat-include = ["owner-*", "feature-*"] ``` corresponds to the `--tagstatinclude tag *` option of _robot_ ## tag-stat-link Type: `dict[str, str | StringExpression] | None` Add external links into `Statistics by Tag`. Pattern can use `*`, `?` and `[]` as wildcards like --test. Characters matching to `*` and `?` wildcards can be used in link and title with syntax %N, where N is index of the match (starting from 1). Examples: ```toml [tag-stat-link] mytag = "http://my.domain:Title" "bug-*" = "http://url/id=%1:Issue Tracker" ``` corresponds to the `--tagstatlink pattern:link:title *` option of _robot_ ## tasks Type: `list[str | StringExpression] | None` Alias to --test. Especially applicable with --rpa. Examples: ```toml tasks = ["My Task", "Smoke*"] ``` corresponds to the `--task name *` option of _robot_ ## testdoc Type: `TestDocProfile | None` Options to be passed to _testdoc_. ## testdoc.doc Type: `str | StringExpression | None` Override the documentation of the top level suite. Examples: ```toml doc = "Very *good* example" ``` ```toml # read documentation from a file doc = "doc_from_file.txt" ``` corresponds to the `-D --doc document` option of _testdoc_ ## testdoc.excludes Type: `list[str | StringExpression] | None` Exclude tests by tags. Examples: ```toml excludes = ["smoke", "wip*"] ``` corresponds to the `-e --exclude tag *` option of _testdoc_ ## testdoc.extend-excludes Type: `list[str | StringExpression] | None` Appends entries to the --exclude option. Exclude tests by tags. Examples: ```toml extend-excludes = ["smoke", "wip*"] ``` corresponds to the `-e --exclude tag *` option of _testdoc_ ## testdoc.extend-includes Type: `list[str | StringExpression] | None` Appends entries to the --include option. Include tests by tags. Examples: ```toml # match tests tagged "foo" or "bar*" extend-includes = ["foo", "bar*"] ``` ```toml # tests with both "foo" and "bar*" tags extend-includes = ["fooANDbar*"] ``` corresponds to the `-i --include tag *` option of _testdoc_ ## testdoc.extend-metadata Type: `dict[str, str | StringExpression] | None` Appends entries to the --metadata option. Set/override metadata of the top level suite. Examples: ```toml [extend-metadata] Version = "1.2" # value can be read from a file (same rules as --doc) ReleaseNotes = "release_notes.txt" ``` corresponds to the `-M --metadata name:value *` option of _testdoc_ ## testdoc.extend-set-tag Type: `list[str | StringExpression] | None` Appends entries to the --settag option. Set given tag(s) to all test cases. Examples: ```toml extend-set-tag = ["my-suite-tag", "ci"] ``` corresponds to the `-G --settag tag *` option of _testdoc_ ## testdoc.extend-suites Type: `list[str | StringExpression] | None` Appends entries to the --suite option. Include suites by name. Examples: ```toml # match a suite by name or by parent.child path extend-suites = ["MySuite", "Tests.SubSuite"] ``` corresponds to the `-s --suite name *` option of _testdoc_ ## testdoc.extend-tests Type: `list[str | StringExpression] | None` Appends entries to the --test option. Include tests by name. Examples: ```toml extend-tests = ["My Test", "Smoke*"] ``` corresponds to the `-t --test name *` option of _testdoc_ ## testdoc.includes Type: `list[str | StringExpression] | None` Include tests by tags. Examples: ```toml # match tests tagged "foo" or "bar*" includes = ["foo", "bar*"] ``` ```toml # tests with both "foo" and "bar*" tags includes = ["fooANDbar*"] ``` corresponds to the `-i --include tag *` option of _testdoc_ ## testdoc.metadata Type: `dict[str, str | StringExpression] | None` Set/override metadata of the top level suite. Examples: ```toml [metadata] Version = "1.2" # value can be read from a file (same rules as --doc) ReleaseNotes = "release_notes.txt" ``` corresponds to the `-M --metadata name:value *` option of _testdoc_ ## testdoc.name Type: `str | StringExpression | None` Override the name of the top level suite. Examples: ```toml name = "My Project" ``` corresponds to the `-N --name name` option of _testdoc_ ## testdoc.set-tag Type: `list[str | StringExpression] | None` Set given tag(s) to all test cases. Examples: ```toml set-tag = ["my-suite-tag", "ci"] ``` corresponds to the `-G --settag tag *` option of _testdoc_ ## testdoc.suites Type: `list[str | StringExpression] | None` Include suites by name. Examples: ```toml # match a suite by name or by parent.child path suites = ["MySuite", "Tests.SubSuite"] ``` corresponds to the `-s --suite name *` option of _testdoc_ ## testdoc.tests Type: `list[str | StringExpression] | None` Include tests by name. Examples: ```toml tests = ["My Test", "Smoke*"] ``` corresponds to the `-t --test name *` option of _testdoc_ ## testdoc.title Type: `str | StringExpression | None` Set the title of the generated documentation. Underscores in the title are converted to spaces. The default title is the name of the top level suite. Examples: ```toml title = "My Library" ``` corresponds to the `-T --title title` option of _testdoc_ ## tests Type: `list[str | StringExpression] | None` Select tests by name or by long name containing also parent suite name like `Parent.Test`. Name is case and space insensitive and it can also be a simple pattern where `*` matches anything, `?` matches any single character, and `[chars]` matches one character in brackets. Examples: ```toml tests = ["My Test", "Smoke*"] ``` corresponds to the `-t --test name *` option of _robot_ ## timestamp-outputs Type: `bool | Flag | None` When this option is used, timestamp in a format `YYYYMMDD-hhmmss` is added to all generated output files between their basename and extension. For example `-T -o output.xml -r report.html -l none` creates files like `output-20070503-154410.xml` and `report-20070503-154410.html`. Examples: ```toml timestamp-outputs = true ``` corresponds to the `-T --timestampoutputs` option of _robot_ ## tool Type: `dict[str, Any] | None` Tool configurations. ## tool.robotcode-analyze.cache Type: `CacheConfig | None` Defines the cache configuration. ## tool.robotcode-analyze.cache.cache-dir Type: `str | None` Path to the cache directory. ## tool.robotcode-analyze.cache.cache-namespaces Type: `bool | None` Enable or disable caching of fully analyzed namespace data to disk. Can speed up startup for large projects by skipping re-analysis of unchanged files. Defaults to enabled. Examples: ```toml [tool.robotcode-analyze.cache] cache_namespaces = false ``` ## tool.robotcode-analyze.cache.extend-ignore-arguments-for-library Type: `list[str] | None` Extend the ignore arguments for library settings. ## tool.robotcode-analyze.cache.extend-ignored-libraries Type: `list[str] | None` Extend the ignored libraries setting. ## tool.robotcode-analyze.cache.extend-ignored-variables Type: `list[str] | None` Extend the ignored variables setting. ## tool.robotcode-analyze.cache.ignore-arguments-for-library Type: `list[str] | None` Specifies a list of libraries for which arguments will be ignored during analysis. This is usefull if you have library that gets variables from a python file as arguments that contains complex data like big dictionaries or complex objects that **RobotCode** can't handle. You can specify a glob pattern that matches the library name or the source file. Examples: - `**/mylibfolder/mylib.py` - `MyLib` - `mylib.subpackage.subpackage` If you change this setting, you may need to run the command `RobotCode: Clear Cache and Restart Language Servers`. _Ensure your library functions correctly without arguments e.g. by defining default values for all arguments._ ## tool.robotcode-analyze.cache.ignored-libraries Type: `list[str] | None` Specifies the library names that should not be cached. This is useful if you have a dynamic or hybrid library that has different keywords depending on the arguments. You can specify a glob pattern that matches the library name or the source file. Examples: - `**/mylibfolder/mylib.py` - `MyLib` - `mylib.subpackage.subpackage` For robot framework internal libraries, you have to specify the full module name like `robot.libraries.Remote`. ## tool.robotcode-analyze.cache.ignored-variables Type: `list[str] | None` Specifies the variable files that should not be cached. This is useful if you have a dynamic or hybrid variable files that has different variables depending on the arguments. You can specify a glob pattern that matches the variable module name or the source file. Examples: - `**/variables/myvars.py` - `MyVariables` - `myvars.subpackage.subpackage` ## tool.robotcode-analyze.code Type: `CodeConfig | None` Defines the code analysis configuration. Examples: ```toml [tool.robotcode-analyze.code] exit_code_mask = "error|warn" ``` ## tool.robotcode-analyze.code.collect-unused Type: `bool | None` Enables collection of unused keyword and unused variable diagnostics. By default this is disabled. Set to `true` to report unused keywords and variables. Examples: ```toml [tool.robotcode-analyze.code] collect_unused = true ``` ## tool.robotcode-analyze.code.exit-code-mask Type: `list[Literal['error', 'warn', 'warning', 'info', 'information', 'hint', 'all']] | None` Specifies the exit code mask for the code analysis. This is useful if you want to ignore certain types of diagnostics in the result code. Examples: ```toml [tool.robotcode-analyze.code] exit_code_mask = ["error", "warn"] ``` ## tool.robotcode-analyze.code.extend-exit-code-mask Type: `list[Literal['error', 'warn', 'warning', 'info', 'information', 'hint', 'all']] | None` Extend the exit code mask setting. ## tool.robotcode-analyze.exclude-patterns Type: `list[str] | None` Specifies glob patterns for excluding files and folders from analysing by the language server. ## tool.robotcode-analyze.extend-cache Type: `CacheConfig | None` Extend the cache configuration. ## tool.robotcode-analyze.extend-cache.cache-dir Type: `str | None` Path to the cache directory. ## tool.robotcode-analyze.extend-cache.cache-namespaces Type: `bool | None` Enable or disable caching of fully analyzed namespace data to disk. Can speed up startup for large projects by skipping re-analysis of unchanged files. Defaults to enabled. Examples: ```toml [tool.robotcode-analyze.cache] cache_namespaces = false ``` ## tool.robotcode-analyze.extend-cache.extend-ignore-arguments-for-library Type: `list[str] | None` Extend the ignore arguments for library settings. ## tool.robotcode-analyze.extend-cache.extend-ignored-libraries Type: `list[str] | None` Extend the ignored libraries setting. ## tool.robotcode-analyze.extend-cache.extend-ignored-variables Type: `list[str] | None` Extend the ignored variables setting. ## tool.robotcode-analyze.extend-cache.ignore-arguments-for-library Type: `list[str] | None` Specifies a list of libraries for which arguments will be ignored during analysis. This is usefull if you have library that gets variables from a python file as arguments that contains complex data like big dictionaries or complex objects that **RobotCode** can't handle. You can specify a glob pattern that matches the library name or the source file. Examples: - `**/mylibfolder/mylib.py` - `MyLib` - `mylib.subpackage.subpackage` If you change this setting, you may need to run the command `RobotCode: Clear Cache and Restart Language Servers`. _Ensure your library functions correctly without arguments e.g. by defining default values for all arguments._ ## tool.robotcode-analyze.extend-cache.ignored-libraries Type: `list[str] | None` Specifies the library names that should not be cached. This is useful if you have a dynamic or hybrid library that has different keywords depending on the arguments. You can specify a glob pattern that matches the library name or the source file. Examples: - `**/mylibfolder/mylib.py` - `MyLib` - `mylib.subpackage.subpackage` For robot framework internal libraries, you have to specify the full module name like `robot.libraries.Remote`. ## tool.robotcode-analyze.extend-cache.ignored-variables Type: `list[str] | None` Specifies the variable files that should not be cached. This is useful if you have a dynamic or hybrid variable files that has different variables depending on the arguments. You can specify a glob pattern that matches the variable module name or the source file. Examples: - `**/variables/myvars.py` - `MyVariables` - `myvars.subpackage.subpackage` ## tool.robotcode-analyze.extend-code Type: `CodeConfig | None` Extend the code analysis configuration. ## tool.robotcode-analyze.extend-code.collect-unused Type: `bool | None` Enables collection of unused keyword and unused variable diagnostics. By default this is disabled. Set to `true` to report unused keywords and variables. Examples: ```toml [tool.robotcode-analyze.code] collect_unused = true ``` ## tool.robotcode-analyze.extend-code.exit-code-mask Type: `list[Literal['error', 'warn', 'warning', 'info', 'information', 'hint', 'all']] | None` Specifies the exit code mask for the code analysis. This is useful if you want to ignore certain types of diagnostics in the result code. Examples: ```toml [tool.robotcode-analyze.code] exit_code_mask = ["error", "warn"] ``` ## tool.robotcode-analyze.extend-code.extend-exit-code-mask Type: `list[Literal['error', 'warn', 'warning', 'info', 'information', 'hint', 'all']] | None` Extend the exit code mask setting. ## tool.robotcode-analyze.extend-exclude-patterns Type: `list[str] | None` Extend the exclude patterns. ## tool.robotcode-analyze.extend-global-library-search-order Type: `list[str] | None` Extend the global library search order setting. ## tool.robotcode-analyze.extend-modifiers Type: `ModifiersConfig | None` Extends the modifiers for the analysis. Examples: ```toml [tool.robotcode-analyze.extend_modifiers] ignore = ["VariableNotFound"] extend-hint = ["KeywordNotFound"] extend-information = ["MultipleKeywords"] ``` ## tool.robotcode-analyze.extend-modifiers.error Type: `list[str] | None` Specifies the diagnostics codes to treat as errors. Examples: ```toml [tool.robotcode-analyze.modifiers] error = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.extend-modifiers.extend-error Type: `list[str] | None` Extend the diagnostics codes to treat as errors. Examples: ```toml [tool.robotcode-analyze.modifiers] extend_error = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.extend-modifiers.extend-hint Type: `list[str] | None` Extend the diagnostics codes to treat as hint. Examples: ```toml [tool.robotcode-analyze.modifiers] extend_hint = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.extend-modifiers.extend-ignore Type: `list[str] | None` Extend the diagnostics codes to ignore. Examples: ```toml [tool.robotcode-analyze.modifiers] extend_ignore = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.extend-modifiers.extend-information Type: `list[str] | None` Extend the diagnostics codes to treat as information. Examples: ```toml [tool.robotcode-analyze.modifiers] extend_information = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.extend-modifiers.extend-warning Type: `list[str] | None` Extend the diagnostics codes to treat as warning. Examples: ```toml [tool.robotcode-analyze.modifiers] extend_warning = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.extend-modifiers.hint Type: `list[str] | None` Specifies the diagnostics codes to treat as hint. Examples: ```toml [tool.robotcode-analyze.modifiers] hint = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.extend-modifiers.ignore Type: `list[str] | None` Specifies the diagnostics codes to ignore. Examples: ```toml [tool.robotcode-analyze.modifiers] ignore = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.extend-modifiers.information Type: `list[str] | None` Specifies the diagnostics codes to treat as information. Examples: ```toml [tool.robotcode-analyze.modifiers] information = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.extend-modifiers.warning Type: `list[str] | None` Specifies the diagnostics codes to treat as warning. Examples: ```toml [tool.robotcode-analyze.modifiers] warning = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.global-library-search-order Type: `list[str] | None` Specifies a global [search order](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#specifying-explicit-priority-between-libraries-and-resources) for libraries and resources. This is usefull when you have libraries containing keywords with the same name. **RobotCode** is unable to analyze the library search order in a file specified with [`Set Library Search Order`](https://robotframework.org/robotframework/latest/libraries/BuiltIn.html#Set%20Library%20Search%20Order), so you can define a global order here. Just make sure to call the `Set Library Search Order` keyword somewhere in your robot file or internally in your library. ## tool.robotcode-analyze.load-library-timeout Type: `int | None` Specifies the timeout in seconds for loading (importing) libraries and variable files during analysis. Increase this if your libraries perform heavy initialization (network calls, large dependency graphs, model loading, etc.). Must be > 0 when set. If you omit this key, RobotCode will instead look for the environment variable `ROBOTCODE_LOAD_LIBRARY_TIMEOUT`; otherwise it will use the internal default `10`. Examples: ```toml [tool.robotcode-analyze] # Fast fail if libraries normally import in < 2s load_library_timeout = 5 ``` ```toml [tool.robotcode-analyze] # Allow heavy bootstrap (e.g. Selenium + large resource trees) load_library_timeout = 30 ``` ```toml [tool.robotcode-analyze] # Omit to use default # load_library_timeout = 15 ``` ## tool.robotcode-analyze.modifiers Type: `ModifiersConfig | None` Defines the modifiers for the analysis. Examples: ```toml [tool.robotcode-analyze.modifiers] ignore = ["VariableNotFound"] hint = ["KeywordNotFound"] information = ["MultipleKeywords"] ``` ## tool.robotcode-analyze.modifiers.error Type: `list[str] | None` Specifies the diagnostics codes to treat as errors. Examples: ```toml [tool.robotcode-analyze.modifiers] error = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.modifiers.extend-error Type: `list[str] | None` Extend the diagnostics codes to treat as errors. Examples: ```toml [tool.robotcode-analyze.modifiers] extend_error = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.modifiers.extend-hint Type: `list[str] | None` Extend the diagnostics codes to treat as hint. Examples: ```toml [tool.robotcode-analyze.modifiers] extend_hint = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.modifiers.extend-ignore Type: `list[str] | None` Extend the diagnostics codes to ignore. Examples: ```toml [tool.robotcode-analyze.modifiers] extend_ignore = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.modifiers.extend-information Type: `list[str] | None` Extend the diagnostics codes to treat as information. Examples: ```toml [tool.robotcode-analyze.modifiers] extend_information = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.modifiers.extend-warning Type: `list[str] | None` Extend the diagnostics codes to treat as warning. Examples: ```toml [tool.robotcode-analyze.modifiers] extend_warning = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.modifiers.hint Type: `list[str] | None` Specifies the diagnostics codes to treat as hint. Examples: ```toml [tool.robotcode-analyze.modifiers] hint = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.modifiers.ignore Type: `list[str] | None` Specifies the diagnostics codes to ignore. Examples: ```toml [tool.robotcode-analyze.modifiers] ignore = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.modifiers.information Type: `list[str] | None` Specifies the diagnostics codes to treat as information. Examples: ```toml [tool.robotcode-analyze.modifiers] information = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.modifiers.warning Type: `list[str] | None` Specifies the diagnostics codes to treat as warning. Examples: ```toml [tool.robotcode-analyze.modifiers] warning = ["VariableNotFound", "multiple-keywords"] ``` ## tool.robotcode-analyze.semantic-model Type: `bool | None` Enable the experimental Semantic Model for code analysis. When enabled, LSP features use the new SemanticAnalyzer instead of the legacy NamespaceAnalyzer. This provides richer analysis including static resolution of nested variables and improved semantic highlighting. **This is experimental and may change without notice.** Can also be set via VS Code setting `robotcode.experimental.semanticModel`. If set in both places, either `true` value enables the feature. Examples: ```toml [tool.robotcode-analyze] semantic-model = true ``` ## variable-files Type: `list[str | StringExpression] | None` Python or YAML file file to read variables from. Possible arguments to the variable file can be given after the path using colon or semicolon as separator. Examples: ```toml variable-files = ["path/vars.yaml", "environment.py:testing"] ``` corresponds to the `-V --variablefile path *` option of _robot_ ## variables Type: `dict[str, str | StringExpression] | None` Set variables in the test data. Only scalar variables with string value are supported and name is given without `${}`. See --variablefile for a more powerful variable setting mechanism. Examples: ```toml # sets ${name} to "Robot" [variables] name = "Robot" ``` corresponds to the `-v --variable name:value *` option of _robot_ ## xunit Type: `str | StringExpression | None` xUnit compatible result file. Not created unless this option is specified. Examples: ```toml xunit = "xunit.xml" ``` corresponds to the `-x --xunit file` option of _robot_ --- URL: "/03_reference/diagnostics-modifiers" LLMS_URL: "/03_reference/diagnostics-modifiers.md" --- # Controlling Diagnostics with Modifiers RobotCode offers advanced static analysis for Robot Framework files. With **diagnostics modifiers** you can control directly in your Robot code which diagnostic messages (lint / analysis errors, warnings, hints) are shown and with what severity. This allows you to, for example: - hide specific rules for individual lines, blocks or files, - adjust the severity of individual messages (hint β†’ warning β†’ error), - temporarily disable diagnostics completely and re-enable them later. ## Basic Concept RobotCode interprets special comments with the prefix `# robotcode:` as **diagnostics modifiers**. General form: ```robot # robotcode: [code1,code2,...] [[code1,code2,...]]... ``` - `action` is one of the predefined actions (see below). - `code` are the diagnostic codes you want to influence (for example `variable-not-found`, `keyword-not-found`, `MultipleKeywords`). If omitted, the action applies to all diagnostics. - You can chain multiple `[...]` segments in the same comment; they are applied in the order written. If the same code appears more than once on the same line, the later action wins. ### Available Actions - `ignore`: Ignore the given diagnostic codes completely (they will not be reported at all). - `hint`: Treat the given codes as hints (lowest severity, usually rendered as faded or informational markers). - `information` / `info`: Treat the given codes as informational messages (above hint, below warning). - `warning` / `warn`: Treat the given codes as warnings (visible but not failing). - `error`: Treat the given codes as errors (highest severity, typically used for CI or "problems" views). - `reset`: Reset the given codes to their default level as defined by the underlying analyzer and any global configuration. - `ignore` without list: Ignore **all** diagnostic messages in the affected scope. - `reset` without list: Reset **all** diagnostic messages to their default; any previous `ignore`, `hint`, `information`, `warning` or `error` modifiers in scope are cleared. Additional rules: - Codes are matched case-insensitively and normalized internally, so `VariableNotFound` and `variable-not-found` are treated the same. - Action names are also case-insensitive; `warn` = `warning`, `info` = `information`. - In global configuration (for example `robot.toml`) you can use `"*"` as a wildcard to match all remaining diagnostics (for example `hint = ["*"]`). - Inline `# robotcode:` modifiers on a specific line always override global configuration from `robot.toml` or CLI settings. - If several modifiers affect the same line and code, the nearest one wins: inline (end-of-line) > indented block > top-level file comment > global/CLI settings. Within one comment the rightmost action for the same code wins. ### Where do the diagnostic codes come from? - Every diagnostic emitted by RobotCode carries a `code` field (LSP `Diagnostic.code`). That value is exactly what you put into `ignore[...]`, `warn[...]`, etc. - Core analyzers define their codes in `robotcode.robot.diagnostics.errors.Error` (for example `VariableNotFound`, `KeywordNotFound`, `MultipleKeywords`). - The simplest way to read the code is in your editor’s Problems/Diagnostics view or in the CLI output of `robotcode analyze`, where the code appears in brackets before the message (e.g. `[W] KeywordNotFound: ...`). - Custom analyzer plugins may emit additional codes; you handle them the same way via modifiers. Common codes (core analyzer) | Code | Meaning (short) | | ---------------------- | --------------------------------------------- | | VariableNotFound | Variable reference could not be resolved. | | KeywordNotFound | Keyword could not be resolved. | | MultipleKeywords | Call matches multiple keywords (ambiguous). | | DeprecatedKeyword | Called keyword is marked deprecated. | | PossibleCircularImport | Potential circular resource/variables import. | Example CLI output (showing `code` before the message) ```bash $ robotcode analyze code tests/example.robot [W] KeywordNotFound: Some Undefined Keyword at tests/example.robot:5:5 [E] VariableNotFound: Variable '${missing}' not found at tests/example.robot:6:11 ``` ## Scope of a Modifier The effect of a modifier depends on its position in the file. ### At the End of a Line A modifier placed at the end of a line affects **only that line**. ```robot *** Keywords *** Keyword Name Log ${arg1} # robotcode: ignore[variable-not-found] ``` Here, the `variable-not-found` error is ignored only for this `Log` call. ### At the Beginning of a Line (Column 0) A modifier placed at the very beginning of a line applies **from that line to the end of the file**, unless it is overridden or reset by another modifier. ```robot # robotcode: ignore[keyword-not-found] *** Test Cases *** Example Test Log Hello Some Undefined Keyword ``` From the position of this modifier to the end of the file, all `keyword-not-found` errors are ignored. ### Inside a Block (Indented) A modifier that is indented and therefore lies inside a block (for example a Test Case, Keyword, IF, FOR) only applies to the **current block**. ```robot *** Keywords *** Example Keyword # robotcode: warn[variable-not-found] Log ${arg1} Another Keyword ``` Within the `Example Keyword` block, `variable-not-found` errors are treated as warnings. ## Typical Use Cases ### Ignore a Single Diagnostic on One Line ```robot *** Keywords *** Show Debug Value Log ${possibly_undefined} # robotcode: ignore[variable-not-found] ``` Useful when you deliberately work with optional or dynamic variables. ### Treat a Rule Globally as "Hint" ```robot # robotcode: hint[MultipleKeywords] *** Test Cases *** My Test Some Keyword Another Keyword ``` The `MultipleKeywords` diagnostic is treated as a hint from this point onward instead of a warning or error. ### Warning Instead of Error for a Specific Rule ```robot # robotcode: warn[variable-not-found] *** Test Cases *** Experimental Test Log ${undefined_variable} ``` `variable-not-found` stays visible but does not block you as an error. ### Combine Multiple Actions in One Comment ```robot # robotcode: warn[keyword-not-found] ignore[variable-not-found] *** Test Cases *** Mixed Strictness Some Undefined Keyword Log ${maybe_missing} ``` Here, `keyword-not-found` is downgraded to a warning while `variable-not-found` is ignored for the same lines; the actions are applied left to right. ### Enforce Strict Checking for a Single Rule ```robot # robotcode: error[keyword-not-found] *** Test Cases *** Critical Test Some Undefined Keyword ``` `keyword-not-found` is treated as an error in this area, even if it is globally configured as a warning or hint. ### Fine-Grained Control with `reset` ```robot # robotcode: error[variable-not-found] *** Test Cases *** Example Test Log ${undefined_variable} # robotcode: reset[variable-not-found] Another Test Log ${undefined_variable} ``` - Until the `reset` modifier, `variable-not-found` is treated as an error. - After `reset[variable-not-found]` the global default severity for this rule is used again. ### Ignore All Diagnostics ```robot # robotcode: ignore *** Test Cases *** Example Test Log ${undefined_variable} Some Undefined Keyword ``` From this point on, all diagnostics are ignored. ### Reset All Diagnostics ```robot # robotcode: ignore *** Test Cases *** Example Test Log ${undefined_variable} # robotcode: reset Another Test Some Undefined Keyword ``` - Until the `reset` modifier, all diagnostics are ignored. - After `reset`, all messages are reported again with their default severity. ## Best Practices - **Keep modifiers local:** Prefer modifiers that are limited to a single line or block instead of globally disabling diagnostics for large parts of a file. - **Document commonly used diagnostic codes:** If you use modifiers frequently in a project, document the most important codes (for example `variable-not-found`, `keyword-not-found`, `MultipleKeywords`) for your team. - **Use `reset` consistently:** Especially when using `ignore` or `error` at the top of a file, make sure there is a clear `reset` later so that the effect does not unintentionally extend when code is moved or added. - **Consider code review:** Because modifiers change the analysis results, they should be part of code review and consciously approved. ### Configuration via `robot.toml` Global diagnostic modifiers are usually configured in the `[tool.robotcode-analyze.modifiers]` section of a TOML configuration file, typically the workspace-level `robot.toml` or the local `.robot.toml` file (see [config.md](config.md) for details). ```toml [tool.robotcode-analyze.modifiers] # Completely ignore very noisy diagnostics ignore = ["MultipleKeywords"] # Downgrade selected rules to warnings warning = ["variable-not-found"] # Upgrade important rules to errors error = ["keyword-not-found"] # Optional: treat all remaining diagnostics as hints hint = ["*"] ``` - `ignore`, `error`, `warning`, `information`, `hint` are lists of diagnostic codes that are merged into the global modifier configuration. - If you want to **add** to existing lists without replacing them (for example when an extension provides defaults), use the matching `extend-*` keys, e.g. `extend-warning = ["variable-not-found"]`. See [config.md](config.md) for the full set. - You can use `"*"` as a wildcard to match all remaining diagnostics if needed. RobotCode tools such as the analyzer, runner and CLI commands read these values from the configured TOML files and pass them as defaults into the diagnostics modifier engine. Inline `# robotcode:` modifiers in `.robot` files are then applied on top and always win for the affected line or block. ### Overriding via editor / language server settings In addition to TOML configuration, the language server can also receive equivalent diagnostic modifier settings from the editor (for example VS Code `settings.json`). These modifier lists are combined with the values from `[tool.robotcode-analyze.modifiers]` and provide a convenient way to override or tweak project defaults per workspace or per developer. In VS Code the corresponding settings live under the `robotcode.analysis.diagnosticModifiers.*` keys, for example: ```jsonc { "robotcode.analysis.diagnosticModifiers.ignore": [ "MultipleKeywords" ], "robotcode.analysis.diagnosticModifiers.warning": [ "variable-not-found" ], "robotcode.analysis.diagnosticModifiers.error": [ "keyword-not-found" ] } ``` Typical scenarios are: - keep the canonical, shared configuration in `robot.toml`, and - use editor settings only to temporarily relax or tighten certain rules (for example on a CI agent or for a specific developer machine). --- URL: "/03_reference/discovering-tests" LLMS_URL: "/03_reference/discovering-tests.md" --- # Discovering Tests, Tasks and Suites ::: tip Installation The `robotcode discover` command comes from the optional **`runner`** package. If it isn't installed yet, add it: ```bash pip install robotcode[runner] # or: pip install robotcode[all] ``` ::: Before you can run, filter, or report on a Robot Framework project you usually want to know what's actually *in* it: which suites live in which directories, what tags each test carries, which `.robot` files Robot would even pick up. **`robotcode discover`** answers those questions without executing a single test. It applies the same configuration and profile pipeline that `robotcode robot` would use to *run* the project β€” so what `discover` reports is exactly what `robot` would see β€” and surfaces the result either as a human-readable tree on the terminal or as structured data for scripts, CI pipelines, and editors. **Who this is for:** - **Developers** opening an unfamiliar project who want a one-shot overview before drilling in. - **CI/CD pipelines** that need a stable inventory of tests / tags / files for sharding, reporting dashboards, or build-time validation. - **Editor and IDE integrations** β€” the JSON output is what the **RobotCode** VS Code extension consumes to build its Test Explorer view. - **AI-driven workflows** β€” coding agents (Claude Code, Cursor, Copilot, …), inventory analyses, test-selection assistants. Letting the agent grep through a tree of `.robot` files is wasteful; `discover` returns just the slice the agent asked for (a tag list, a file list, the test tree under one path). - **Test-selection scripts** that build `-bl/--by-longname` lists for `robotcode robot` β€” pre-filtering tests for sharded CI matrices, regression sets, or scheduled smoke runs. Typical things you can do with it: - get a tree view of every suite, sub-suite, test and task the active profile would discover - list just the tests (or just the tasks) one per line, with source paths and tags - list every distinct tag in the project with the tests it tags - list the source files Robot Framework would even consider parsing - check the Robot Framework version, Python version and environment the tooling is running under The seven subcommands share the same configuration, search, and output-format pipeline β€” once you've learned one the others follow: | Subcommand | Use it when you want to … | |---|---| | [`all`](#all-the-full-tree) | … see the whole tree (workspace β†’ suite β†’ sub-suite β†’ test/task) | | [`tests`](#tests-flat-list-of-tests) | … list tests one per line (typed `test`) | | [`tasks`](#tasks-flat-list-of-tasks) | … list tasks one per line (typed `task`, RPA mode) | | [`suites`](#suites-flat-list-of-suites) | … list suites only β€” no per-test rows | | [`tags`](#tags-tag--tests-dictionary) | … build a `tag β†’ [tests]` index for triage or dashboards | | [`files`](#files-source-files-robot-would-parse) | … list every `.robot` / `.resource` file Robot would even consider | | [`info`](#info-environment-and-version) | … check the active Robot / Python / RobotCode versions and environment | This guide is split in two: 1. **[Part 1 β€” Using the commands](#quick-start)** walks through every subcommand from the terminal perspective: what it does, what shows up on the screen, and what filters and flags are available. 2. **[Part 2 β€” JSON reference](#json-reference)** documents the structured output for scripts, CI pipelines, and editor integrations β€” the JSON schema of every subcommand plus jq-based recipes. For the exhaustive option list see the auto-generated [CLI reference](cli.md#discover). ## Quick start ```bash # Workspace tree β€” every suite, every test, with tags robotcode discover all # Flat list of tests, one per line robotcode discover tests # Just the test names matching "Login", in the current profile's scope robotcode discover tests --search Login # A tag β†’ tests dictionary robotcode discover tags # Which source files would Robot even parse? robotcode discover files # Active Robot / Python / RobotCode versions + environment robotcode discover info ``` If you don't pass paths or filters, `discover` falls back to the **default paths from your active `robot.toml` profile** β€” the same logic `robotcode robot` uses. ## How `discover` finds your project `discover` runs the same configuration pipeline as `robotcode robot`: 1. **Profile resolution.** `robot.toml` is loaded and combined with any `--profile` selectors. The resulting profile contributes the default paths (`paths = [...]`), variables, library paths, and any other Robot Framework settings. 2. **Argument layering.** Positional `ROBOT_OPTIONS_AND_ARGS` you pass on the command line are appended *after* the profile's settings β€” Robot's normal precedence rules apply. So `robotcode discover tests --include smoke ./tests/login` picks up the profile's `paths` *unless* you give explicit paths (then those win), and adds `--include smoke` on top of any profile-level includes. 3. **Static parsing only.** `discover` never executes a keyword. It walks the suite tree the same way Robot's `--dryrun` would but stops earlier β€” at parse time. Library imports, variable files, listeners, and pre-run modifiers are loaded only as far as needed to resolve the tree. If you want to discover something *outside* your profile (a one-off file, a specific directory), pass it as a positional argument: ```bash robotcode discover tests path/to/suite.robot robotcode discover all path/to/dir/ path/to/other/ ``` You can also pass any standard `robot` argument through β€” `--include`, `--exclude`, `--suite`, `--test`, `--variable`, `--pythonpath`, … See [Robot-native filters](#robot-native-filters) below. ## Output formats The default TEXT output is meant for humans reading in a terminal β€” colourised, paginated. For pipelines, scripts, editor integrations, and AI agents, the global `-f/--format` flag β€” set **before** the subcommand β€” switches to a stable structured format: ```bash robotcode discover all # default: human-readable TEXT robotcode --format json discover all # compact JSON, one line robotcode --format json_indent discover all # pretty-printed JSON robotcode --format toml discover all # TOML ``` If you only ever look at terminal output, the following sections cover everything you need. For the JSON shape of any subcommand, jump to the [JSON reference](#json-reference). Pager and colour handling is identical to `results` β€” see [Pager and colour](analyzing-results.md#pager-and-colour-in-the-terminal) for the details. ## `all` β€” the full tree `all` prints the complete hierarchy the active profile resolves to: the workspace root, every suite and sub-suite below it, and every test or task inside those suites. It's the closest thing to "show me what's in this project". ```bash robotcode discover all robotcode discover all ./tests/login # restrict to a path robotcode discover all --include smoke # restrict to a tag ``` Sample output: ``` Suite: MyProject (tests/) Suite: MyProject.Login (tests/login/) Test: MyProject.Login.Bad Password (tests/login/test_login.robot:14) Tags: regression, smoke Test: MyProject.Login.Good Password (tests/login/test_login.robot:22) Tags: smoke Statistics: - Suites: 4 - Suites with tests: 3 - Tests: 18 ``` ### Flag reference | Flag | Effect | |---|---| | `--tags / --no-tags` | Show or hide the `Tags:` line under each test/task. **Default: on.** | | `--full-paths / --no-full-paths` | Absolute source paths. Default: relative to cwd. | | `--search TEXT` / `--search-regex PATTERN` | Prune the tree to tests matching the pattern; surviving tests keep their full ancestor chain. See [Search](#search). | | `-bl NAME` / `-ebl NAME` | Include/exclude tests, tasks or suites by exact long name. See [Robot-native filters](#robot-native-filters). | | *any standard `robot` flag* | `--include`, `--exclude`, `--suite`, `--test`, `--variable`, `--pythonpath`, … passed through to the discovery pipeline. | A diagnostics footer is added to TEXT output when parsing emits warnings or errors (deprecated section headers, duplicate test names, unparseable files). In JSON they land in the `diagnostics` field β€” see [diagnostics](#diagnostics). ## `tests` β€” flat list of tests `tests` collapses the hierarchy: one row per test, with full long name and source location. The natural input for scripts that need a list of test identifiers. ```bash robotcode discover tests robotcode discover tests --tags # add a `Tags: ...` line per test robotcode discover tests --include smoke # filter by tag robotcode discover tests --search "Login" # substring search robotcode discover tests path/to/suite.robot # one suite only ``` Sample output: ``` Test: MyProject.Login.Bad Password (tests/login/test_login.robot:14) Test: MyProject.Login.Good Password (tests/login/test_login.robot:22) Test: MyProject.Checkout.Empty Cart (tests/checkout/test_checkout.robot:8) ``` ### Flag reference | Flag | Effect | |---|---| | `--tags / --no-tags` | Include a `Tags:` line per test. **Default: off** (tests are always one-line in TEXT). | | `--full-paths / --no-full-paths` | Absolute source paths. | | `--search TEXT` / `--search-regex PATTERN` | Filter by name/source/body/tags. | | `-bl NAME` / `-ebl NAME` | Long-name include/exclude. | | *any standard `robot` flag* | Pass-through. | Tasks defined with `*** Tasks ***` are intentionally **not** in this list β€” use [`tasks`](#tasks-flat-list-of-tasks) for those. ## `tasks` β€” flat list of tasks `tasks` is the RPA twin of `tests`: one row per task. The TEXT output and flag set mirror `tests`; only the row label differs (`Task: …`). ```bash robotcode discover tasks robotcode discover tasks --tags ``` In a mixed-mode suite (rare β€” Robot doesn't recommend it), `tests` shows the `*** Test Cases ***` half and `tasks` shows the `*** Tasks ***` half. A project where the active `robot.toml` profile sets `rpa = true` puts everything under `tasks`. ## `suites` β€” flat list of suites `suites` lists every suite the active profile resolves, one per line, no per-test detail. Useful when you want to know *which suites exist* without scrolling past hundreds of tests, or to build a suite-by-suite shard plan for CI. ```bash robotcode discover suites robotcode discover suites --include smoke # only suites with a smoke test ``` Sample output: ``` MyProject (tests/) MyProject.Login (tests/login/) MyProject.Checkout (tests/checkout/) ``` A suite with no surviving tests after filtering disappears from the list β€” `--include smoke` against a suite where nothing is tagged `smoke` will drop that suite. ## `tags` β€” tag β†’ tests dictionary `tags` builds an index of every distinct tag in the discovered suite tree. The default TEXT output is the tag list alone; `--tests` and `--tasks` expand each tag with the tests / tasks it covers. ```bash robotcode discover tags # just the tags robotcode discover tags --tests # tag β†’ tests, indented robotcode discover tags -i smoke # tags appearing in the smoke subset robotcode discover tags --not-normalized # keep the original tag spelling ``` Sample output (`--tests`): ``` smoke Test: MyProject.Login.Good Password (tests/login/test_login.robot:22) Test: MyProject.Login.Bad Password (tests/login/test_login.robot:14) regression Test: MyProject.Login.Bad Password (tests/login/test_login.robot:14) ``` ### Flag reference | Flag | Effect | |---|---| | `--normalized / --not-normalized` | Whether tag keys are normalised (lowercase, no whitespace, no underscore). **Default: on.** `Bug 1` / `bug_1` / `BUG1` collapse to a single `bug1` entry; with `--not-normalized` the three variants stay separate. | | `--tests / --no-tests` | Add the tests carrying each tag. Default: off. | | `--tasks / --no-tasks` | Add the tasks carrying each tag. Default: off. | | `--full-paths` | Absolute source paths in the expanded child rows. | | `--search TEXT` / `--search-regex PATTERN` | Filter the underlying test set first; only tags surviving on at least one matching test appear. | | `-bl` / `-ebl` / *any `robot` flag* | Pass-through. | ### Normalisation in practice The `--normalized` default matches Robot Framework's own tag-matching semantics: `--include "bug 1"` matches tests tagged `bug_1` or `BUG1`. Disable it (`--not-normalized`) when you want to **audit tag hygiene** β€” three distinct dict keys for `Bug 1` / `bug_1` / `BUG1` make accidental variants pop. ## `files` β€” source files Robot would parse `files` lists every `.robot` and `.resource` file Robot Framework would even consider loading from the given paths (or the profile's default paths), honouring `.gitignore` / [`.robotignore`](./ignoring-files.md). ```bash robotcode discover files # respects profile paths robotcode discover files ./tests ./resources # explicit directories robotcode discover files --search "checkout" # filename substring filter ``` Sample output: ``` tests/login/test_login.robot tests/login/resources/login_keywords.resource tests/checkout/test_checkout.robot ``` Files under directories ignored by `.gitignore` / `.robotignore` are excluded automatically. Use this when you need to feed a list of files into another tool (linter, formatter, custom pre-commit hook) and want exactly the set Robot would walk. ### Flag reference | Flag | Effect | |---|---| | `--full-paths / --no-full-paths` | Absolute paths. Default: relative to cwd. | | `--search TEXT` / `--search-regex PATTERN` | Filter by path/filename substring or regex. | ## `info` β€” environment and version `info` reports the versions and platform `robotcode` is running under β€” useful for bug reports, CI metadata, and "does this build have the right Robot version" checks. ```bash robotcode discover info robotcode --format json discover info ``` TEXT output: ``` robotVersionString: 7.4.2 robotcodeVersionString: 1.6.0 pythonVersionString: 3.13.2 executable: .venv/bin/python platform: linux system: Linux … ``` Set `ROBOT_OPTIONS`, `ROBOT_SYSLOG_FILE`, `ROBOT_SYSLOG_LEVEL` or `ROBOT_INTERNAL_TRACES` and they're echoed back under `robotEnv`, so you can verify the run environment matches expectations. ## Robot-native filters Every `discover` subcommand (except `info` and `files`) passes through to Robot Framework's own filtering machinery. Anything you'd write on a `robot` command line works here: | Flag | Effect | |---|---| | `-i / --include TAG_PATTERN` | Include tests with a matching tag. Supports Robot's `AND`/`OR`/`NOT` syntax and globs (`*`, `?`). | | `-e / --exclude TAG_PATTERN` | Exclude tests with a matching tag. | | `-s / --suite NAME` | Limit to suites whose name matches the glob. | | `-t / --test NAME` | Limit to tests whose name matches the glob (`--task` is the RPA alias). | | `-bl / --by-longname NAME` | Exact long-name include β€” no glob expansion. | | `-ebl / --exclude-by-longname NAME` | Exact long-name exclude. | | `--variable NAME:VALUE`, `--pythonpath PATH`, … | Anything else Robot accepts. | Filters compose β€” `--include smoke --exclude wip` means "smoke and not wip". ### `--by-longname` vs `--suite` / `--test` - `-s` / `-t` are **glob** matches. - `-bl` / `-ebl` are **exact** matches against the full long name. They mirror `robotcode robot --by-longname` so you can hand the same names to `robot` and `discover`. Use `-bl` when you have a precise name (often pasted from a failure list or a build log); use `-s/-t` when you want pattern matching. ## Search `--search` and `--search-regex` are **mutually exclusive** (passing both is a usage error). They prune the discovered tree to tests matching the pattern; surviving tests keep their full ancestor chain so `discover all --search Login` still shows `MyProject β†’ MyProject.Login β†’ Login.Bad Password` with sibling suites pruned. The search applies across: - the test's `name` and full long name - the test's `source` path - the test's `[Documentation]`, `[Template]` and `[Timeout]` - the test's tags (Robot's normalisation rules apply) - every keyword call's name, arguments and assigned variables inside the test body - FOR/WHILE/IF conditions, VAR/RETURN values, EXCEPT patterns, GROUP names - any ancestor suite's `Documentation` or `Metadata` β€” a hit on a suite-level field keeps every test underneath it | Flag | Semantics | |---|---| | `--search TEXT` | Case-insensitive substring match. No metacharacters; `[` and `*` are literal. | | `--search-regex PATTERN` | Python regex, **case-sensitive** by default. Prefix with `(?i)` for case-insensitive matching. | Tag targets are matched with normalisation (lowercase, whitespace and underscores ignored), so `--search "bug 1"` matches tests tagged `bug_1`, `Bug1`, or `BUG 1`. All other targets are matched literally. ```bash robotcode discover tests --search "Login" robotcode discover all --search-regex 'Login.*(Bad|Good)' robotcode discover tests --search-regex '(?i)checkout' robotcode discover tags --search smoke robotcode discover files --search "_keywords" ``` ### Highlighting in the terminal Matches are highlighted inline in the TEXT output with a yellow background so they're easy to scan. Structured output (JSON/TOML) is unchanged β€” searching only filters, it doesn't add markup. ### Search on `tags` and `files` `--search` works on these too: - **`tags`** filters the underlying tests first; tag keys whose tests are all dropped disappear from the dictionary. So `discover tags --search Login` is "what tags are involved in the Login subset". - **`files`** matches the filename / path itself β€” no body inspection. So `discover files --search "_keywords"` is "every file whose path contains `_keywords`". ### Invalid patterns An unparseable regex (e.g. `[unclosed`) yields a usage error pinpointing where the pattern failed to compile. The command exits non-zero before parsing any suite. ## Tips for terminal use - **TEXT output is markdown.** On a coloured TTY the markdown is rendered to themed ANSI via `rich` (and paged if longer than your terminal); on pipes or with `--no-color` the raw markdown goes through verbatim β€” paste it into a PR description, a Slack message, or feed it straight to an LLM. - **Quote your globs.** `--suite "*.Login.*"` and `--test "Test ?"` need quotes so the shell doesn't expand them against the local filesystem first. - **`-bl` is for exact names, `-t` is for patterns.** When you copy a test long-name out of another tool's output, `-bl` is usually what you want β€” no need to escape glob characters. - **Pre-filter before piping into `robot`.** `robotcode discover tests --include smoke -f json | jq -r '.items[].longname'` gives you a stable list of long names you can hand back to `robotcode robot -bl ...` for sharded CI runs. - **Parse errors don't stop discovery.** Files with syntax errors still appear in the tree; their problems land in the [`diagnostics`](#diagnostics) field. Pipe through `--format json` and check `.diagnostics` for build-time gating. --- # JSON reference When you set `-f json` (or `-f json_indent` for pretty-printed, or `-f toml`) between `robotcode` and the subcommand, every `discover` command emits structured data instead of the terminal-formatted text. This is what CI pipelines, scripts, editor integrations, and AI agents consume. ```bash robotcode --format json discover all robotcode --format json discover tests --include smoke robotcode --format json discover tags --tests ``` ## Schema rules A few rules hold across every subcommand: - **camelCase keys.** `fullName`, `relSource`, `needsParseInclude`, etc. - **Optional fields are omitted, not `null`.** A `null` literal never appears. If a field has no value (a test with no tags, a suite with no children), the key is simply absent. - **Empty array β‰  missing field.** A field listed in the schema may be `[]` if the section "exists but is empty"; a field absent entirely means the section wasn't computed for this run. `// []` in jq smooths over the difference. - **Stability.** Fields are appended over time, never renamed or removed in place. Existing consumers keep working. ## `TestItem` β€” the common shape Every subcommand that returns tests/tasks/suites uses the same `TestItem` schema: ```json { "type": "test", "id": "/abs/path/test_login.robot;MyProject.Login.Bad Password;42", "name": "Bad Password", "longname": "MyProject.Login.Bad Password", "lineno": 42, "uri": "file:///abs/path/test_login.robot", "relSource": "tests/login/test_login.robot", "source": "/abs/path/test_login.robot", "needsParseInclude": true, "tags": ["smoke", "regression"], "range": { "start": { "line": 41, "character": 0 }, "end": { "line": 41, "character": 0 } }, "children": [ /* nested TestItems for type=suite/workspace */ ], "description": "Test docstring (when set)", "error": "Parse error message (when this item failed to parse)", "rpa": false } ``` Field notes: - `type` is one of `"workspace"`, `"suite"`, `"test"`, `"task"`. `workspace` is the synthetic root that wraps the actual project directory. - `id` is a stable identifier (`source;longname;lineno` for tests/tasks; `source;longname` for suites). Editor integrations use this to track which `TestItem` corresponds to which on-disk artefact across reloads. - `lineno` is 1-based; `range.start.line` / `range.end.line` are 0-based (LSP convention). Both refer to the same line of source. - `uri` is a `file://` URI of the source file β€” same format the Language Server Protocol uses. - `needsParseInclude` is true when re-parsing this item requires re-running Robot 6.1+'s include-resolution pass (resource-file `Library` imports with arguments). - `tags` are normalised (`Bug 1`, `bug_1`, `Bug1` all come through as `"bug1"`) and only present when the item has at least one tag. - `children` is the nested-tree field β€” present on `workspace` and `suite` items, absent on `test` / `task`. - `range` follows the LSP `Range` shape so editors can highlight the source span. ## `all` / `tests` / `tasks` / `suites` JSON All four subcommands wrap their items in a `ResultItem`: ```json { "items": [ /* TestItem(s) */ ], "diagnostics": { /* see below */ }, "filtersApplied": { "search": "Login" } } ``` Per subcommand: - **`all`** β€” `items` has exactly one entry: the `workspace` root, whose `children` is the suite tree. - **`tests`** / **`tasks`** β€” `items` is a flat list of `test` / `task` entries respectively. - **`suites`** β€” `items` is a flat list of `suite` entries (no children β€” drill into the source files separately if you want per-suite tests). `diagnostics` and `filtersApplied` are both optional and absent when empty / unused. ## `tags` JSON ```json { "tags": { "bug1": [ /* TestItems carrying this tag */ ], "smoke": [ /* … */ ] }, "filtersApplied": { "include": ["smoke"] } } ``` Field notes: - `tags` is always an object β€” possibly empty `{}` if no tag survived the filter chain. - Keys are tag names; normalised by default, original spellings preserved with `--not-normalized`. - Each value is an array of `TestItem` objects (the tests / tasks carrying that tag). - A test with `n` tags appears in `n` entries. ## `files` JSON ```json [ "tests/login/test_login.robot", "tests/login/resources/login_keywords.resource", "tests/checkout/test_checkout.robot" ] ``` `files` is a plain JSON array of path strings β€” relative to cwd by default, absolute with `--full-paths`. No wrapper object, no per-file metadata. If you need richer info, use `discover all` and walk the tree. ## `info` JSON ```json { "robotVersionString": "7.4.2", "robotEnv": { "ROBOT_OPTIONS": "--include smoke" }, "robotcodeVersionString": "1.6.0", "pythonVersionString": "3.13.2", "executable": ".venv/bin/python", "machine": "x86_64", "processor": "x86_64", "platform": "linux", "system": "Linux", "systemVersion": "#1 SMP …" } ``` Field notes: - `robotEnv` echoes back any of `ROBOT_OPTIONS`, `ROBOT_SYSLOG_FILE`, `ROBOT_SYSLOG_LEVEL`, `ROBOT_INTERNAL_TRACES` that were set, and is absent (or `{}`) when none of them are. ## `diagnostics` When parsing a file produces a warning or error (deprecated syntax, duplicate test names, unparseable file …), `discover all/tests/tasks/suites` reports it as an LSP-style diagnostic keyed by the source's `file://` URI: ```json "diagnostics": { "file:///abs/path/parse_error.robot": [ { "range": { "start": { "line": 13, "character": 0 }, "end": { "line": 13, "character": 0 } }, "message": "Singular section headers like '*** Keyword ***' are deprecated. Use plural format like '*** Keywords ***' instead.", "severity": 2, "code": "discover", "source": "robotcode.discover" } ] } ``` Field notes: - `severity` follows LSP's enum: `1` = Error, `2` = Warning, `3` = Information, `4` = Hint. - A file whose parser failed entirely still contributes whatever tests Robot could recover; the unrecoverable parts come through here. - `diagnostics` is omitted when nothing fired. ## `filtersApplied` Every subcommand that accepts search flags includes a `filtersApplied` field when one was set: ```json "filtersApplied": { "search": "Login" } ``` ```json "filtersApplied": { "search-regex": "(?i)login" } ``` The Robot-native filters (`--include`, `--exclude`, `--suite`, `--test`, `-bl`, `-ebl`) are **not** echoed here β€” they're handed straight to Robot Framework's filter pipeline and the effect is visible in the surviving `items` set. ## CI recipes A grab-bag of jq-based recipes. Pin `-f json` between `robotcode` and the subcommand to lock the format. ### Build a shard plan ```bash # List of suite long names β†’ fed into a CI matrix robotcode --format json discover suites \ | jq -r '.items[].longname' # Long names of every smoke test robotcode --format json discover tests --include smoke \ | jq -r '.items[].longname' ``` ### Fail the build on parse errors ```bash robotcode --format json discover all \ | jq -e '(.diagnostics // {}) | map(.[] | select(.severity == 1)) | length == 0' ``` ### List every file the test pipeline would touch ```bash robotcode --format json discover files | jq -r '.[]' ``` ### Build a tag report ```bash # tag β†’ count of tests carrying it robotcode --format json discover tags \ | jq '.tags | map_values(length)' # Tags with fewer than 3 tests (candidates for cleanup) robotcode --format json discover tags \ | jq '.tags | to_entries | map(select(.value | length < 3)) | from_entries' ``` ### Check the Robot version in CI ```bash robotcode --format json discover info | jq -r .robotVersionString ``` ### Find tests touched by a specific keyword ```bash # Every test whose body calls `Open Browser` robotcode --format json discover tests --search "Open Browser" \ | jq -r '.items[].longname' ``` --- For the per-flag reference, see the auto-generated [CLI reference](cli.md#discover). --- URL: "/03_reference/ignoring-files" LLMS_URL: "/03_reference/ignoring-files.md" --- # Excluding Files with `.robotignore` When RobotCode looks at a project β€” discovering suites, running static analysis, or providing diagnostics and completion in the editor β€” it walks the source tree to find the `.robot` and `.resource` files it should care about. On a small project that is harmless, but real projects are rarely just Robot Framework. The same tree usually holds build output and dependencies (`dist/`, `build/`, `target/`, `node_modules/`, and the like), configuration folders, archived suites, vendored libraries, or the source of whatever application you are testing β€” none of which RobotCode needs to read. Walking and analysing them anyway costs time and memory for no benefit. A **`.robotignore`** file tells RobotCode which paths to skip. By default RobotCode honours your `.gitignore`. But Robot Framework's own built-in exclusion (applied when it collects suites to run) only skips dotted, underscored, and `CVS/` names β€” far too little for a modern repository, where the directories that actually slow things down (`node_modules`, virtual environments, build output, large test-data folders) are none of those. A `.robotignore` fills that gap. Just as importantly, it lets you decide what RobotCode skips *independently* of what you keep out of version control β€” the two are rarely the same question, as explained [below](#robotignore-and-gitignore). ::: tip Works everywhere, no setup `.robotignore` is honoured by the language server in the editor as well as by the `robotcode discover` and `robotcode analyze` commands β€” the same ignore rules are applied wherever RobotCode walks your files. There is nothing to install or enable β€” drop the file in and it takes effect. ::: ## Quick start 1. Create a file named `.robotignore` in your **project root** β€” the same directory you point Robot Framework at. This is where discovery and analysis begin, so a `.robotignore` here governs the whole project. 2. Add one pattern per line. The syntax is identical to `.gitignore`, so most of what you already know carries over: ```gitignore results/ node_modules/ **/generated/ ``` 3. Confirm the result. `robotcode discover files` prints exactly the set of files RobotCode loads *after* applying your ignore rules, so you can see at a glance whether a directory really dropped out: ```bash robotcode discover files ``` If a path you expected to disappear is still listed β€” or one you need has gone missing β€” tweak the pattern and run the command again. You are editing a plain text file, so there is no cache to clear: the next time you run the command, it walks with the new rules. (In the editor, saving a `.robotignore` reloads the language server automatically β€” see [Reloading](#reloading).) ## Syntax `.robotignore` uses the exact same pattern language as `.gitignore`. If you have written a `.gitignore` before, there is nothing new to learn here: ```gitignore # a comment starts with '#' # match a directory anywhere in the tree (trailing slash = directories only) results/ node_modules/ coverage/ # match by name at any depth (no slash) *.bak *.tmp # anchor to this directory only (leading slash) /legacy/ # match nested paths with '**' **/generated/ tests/**/snapshots/ # exclude a folder's contents but keep one file # (use '/*', not 'fixtures/' β€” '!' can't re-include inside a fully excluded folder) fixtures/* !fixtures/shared.resource ``` A few rules are worth keeping in mind. Patterns are matched relative to the directory the `.robotignore` lives in, not the current working directory. Order matters: a later rule overrides an earlier one, and a leading `!` re-includes a path that an earlier rule excluded. A trailing slash restricts a pattern to directories, and a leading slash anchors it to the file's own directory instead of matching at any depth. All of this is identical to Git. ### Pattern reference | Pattern | Matches | | --- | --- | | `results/` | a directory named `results` anywhere in the tree, and everything inside it | | `*.bak` | any file ending in `.bak`, at any depth | | `/build/` | `build/` only in the same directory as the `.robotignore` | | `**/generated/` | a `generated/` directory at any depth | | `tests/**/data/` | a `data/` directory anywhere below `tests/` | | `!keep.resource` | re-include a path excluded by an earlier rule | ::: warning You can't re-include inside a fully excluded folder This is a standard Git behaviour, not a RobotCode quirk, but it trips everyone up at least once: once a whole directory is excluded (`legacy/`), a later `!legacy/common/` has no effect, because RobotCode never descends into an excluded directory in the first place β€” so there is nothing for the negation to re-include. Exclude the directory's *contents* instead, which leaves the directory itself walkable so the negation can apply: ```gitignore legacy/* !legacy/common/ ``` ::: ## What's ignored by default Even with no `.robotignore` at all, RobotCode never walks into `.git/`, `.svn/`, `CVS/`, or any file or directory whose name starts with a dot β€” `.venv/`, `.cache/`, `.tox/`, and so on (on Windows, items with the hidden attribute or a leading `$` are skipped too). These are skipped in every context (discovery, analysis, and the editor), so listing them in a `.robotignore` is redundant and you can leave them out. Underscore-prefixed names are a partial exception, and the distinction is worth understanding so you are not surprised. Robot Framework's own *suite collector* ignores names that begin with `.` or `_`, which is why a `_drafts/` folder never turns into a runnable suite. That rule, however, only applies when Robot Framework is collecting suites to **run**. RobotCode's static side β€” the language server, `robotcode analyze`, and `robotcode discover files` β€” still walks `_`-prefixed files and analyses them. This is deliberate: a `_keywords.resource` that other files import should absolutely get completion and diagnostics in the editor. The consequence is simply that if you want a `_`-named folder kept out of analysis *as well*, you do have to list it in `.robotignore` β€” the underscore convention alone won't hide it from the editor. ## `.robotignore` and `.gitignore` RobotCode uses **one or the other β€” never both merged**: - If a `.robotignore` is present at the project root, RobotCode uses `.robotignore` files throughout the project and **ignores every `.gitignore`**. - If there is no `.robotignore` anywhere, RobotCode falls back to your `.gitignore` files. The moment you add a `.robotignore`, you opt out of `.gitignore` for RobotCode entirely. That can feel surprising at first, but it is deliberate, and the reason is that the two files answer different questions. `.gitignore` describes what should not be committed to version control; that is rarely the same set as what RobotCode should skip. A build artifact may be git-ignored yet still worth nothing to analyse; a large folder of vendored test data may be committed on purpose yet pointless to walk. Trying to merge two rule sets with different intentions tends to produce confusing, hard-to-predict results. So once you reach for a `.robotignore`, RobotCode treats it as the single source of truth for "what RobotCode looks at" and leaves your Git configuration untouched β€” and unconsulted. In practice this means a `.robotignore` is a small, self-contained file you can reason about on its own, without having to mentally diff it against everything in your `.gitignore`. ::: tip Define it at the project root Discovery and analysis always start at the project root, so that is where a `.robotignore` belongs. Placed there, it puts the whole project into "`.robotignore` mode"; placed only deep in a subtree, it may never be reached if a `.gitignore` higher up has already taken over. When in doubt, keep one `.robotignore` at the root. ::: ## Nested `.robotignore` files You are not limited to a single file. You can drop additional `.robotignore` files into subdirectories, and they cascade exactly like Git: a `.robotignore` applies to its own directory and everything beneath it, and a deeper file *adds to* the rules inherited from above. A deeper file can also re-include, with `!`, something a parent excluded β€” as long as the parent excluded its contents rather than the whole directory (see the warning above). Throughout this cascade you stay in `.robotignore` mode: `.gitignore` files are ignored at every level, not just at the root. This is useful when a particular subtree needs extra exclusions that don't make sense for the rest of the project β€” for example a legacy area with its own generated junk: ```text my-project/ β”œβ”€β”€ .robotignore # project-wide excludes β”œβ”€β”€ tests/ β”‚ └── … └── legacy/ └── .robotignore # extra excludes that only apply under legacy/ ``` ## A realistic example To see how the pieces fit together, here is a `.robotignore` you might find at the root of a mixed project β€” a Robot Framework test suite living alongside a web front-end, some build tooling, and an archive of old suites: ```gitignore # build output and dependencies dist/ build/ target/ node_modules/ # Robot Framework run artifacts results/ output.xml log.html report.html # generated and vendored code **/generated/ third_party/ # scratch files and backups *.bak **/tmp/ # a large archive of legacy suites we don't want analysed… legacy/* # …except for the shared resources the active suites still import !legacy/common/ ``` Read top to bottom, this keeps RobotCode focused on the suites and resources you actually work with: the front-end's dependencies and the project's build output are gone, run artifacts from previous executions don't get re-parsed, and the bulky legacy archive is excluded β€” except for the shared resource files the live suites still import, which the final `!legacy/common/` rule keeps visible. ## Where it applies A `.robotignore` is honoured everywhere RobotCode walks the file system β€” the same ignore rules apply on the command line and in the editor alike: - **Test and suite discovery** β€” [`robotcode discover`](./discovering-tests.md) and the editor's Test Explorer. Excluded directories don't appear in the discovered tree, which keeps both the CLI output and the Test Explorer focused on real suites. - **Static code analysis** β€” [`robotcode analyze`](./analyzing-code.md). Excluded files are never analysed by `robotcode analyze`, so they produce no diagnostics in a lint run. - **The language server** β€” diagnostics, completion, and namespace resolution in the editor. Excluded files are never loaded, so they don't contribute keywords or variables and don't slow the editor down. ## Verifying what's ignored When a pattern doesn't behave the way you expect, don't guess β€” ask RobotCode. The quickest way to see what your rules actually do is [`robotcode discover files`](./discovering-tests.md#files-β€”-source-files-robot-would-parse), which lists every `.robot` and `.resource` file RobotCode would load *after* applying `.robotignore`: ```bash # every file RobotCode currently considers robotcode discover files # narrow it down to one area while you tune patterns robotcode discover files ./tests ``` If an excluded directory still appears in the list, your pattern isn't matching it β€” check the anchoring (`/foo` vs `foo`) and the trailing slash. If a file you need has vanished, an earlier rule is too broad, and you may need a `!` re-include to bring it back (remembering the fully-excluded-folder caveat above). Iterating against this command is far faster than restarting the editor to see what changed. ## Performance on large projects This is where `.robotignore` earns its keep. For every `.robot` and `.resource` file it loads, the language server builds a namespace and resolves that file's imports β€” and on a large workspace that work, repeated across thousands of files, is often the dominant cost. One of the most effective things you can do about it is reduce how many files there are to analyse in the first place. Excluding directories you never actually work in β€” generated code, vendored libraries, build output, or a large archive of legacy suites β€” removes them from analysis entirely: no namespace is built and no imports are resolved for them. On big projects this can reduce both analysis time and the language server's memory use, and because a `.robotignore` is trivial to add and easy to verify with `robotcode discover files`, it is usually the first thing to try β€” before reaching for finer-grained analysis settings such as `robotcode.analysis.diagnosticMode`, which controls whether diagnostics are reported only on the files you have open or across the whole workspace. ## Reloading A `.robotignore` is read while RobotCode walks the workspace, so a change to it has to be applied project-wide. Editing a `.robotignore` (or a `.gitignore`) therefore restarts the language server, which re-walks the tree with the new rules and rebuilds its view of the project. You don't need to do anything beyond saving the file. ## See also - [`robotcode discover files`](./discovering-tests.md#files-β€”-source-files-robot-would-parse) β€” verify exactly which files survive your ignore rules. - [Analyzing Code](./analyzing-code.md) β€” the static analysis that honours `.robotignore`. - [Diagnostics Modifiers](./diagnostics-modifiers.md) β€” suppress individual diagnostics instead of whole files, when excluding a file is too coarse a tool. --- URL: "/03_reference/repl" LLMS_URL: "/03_reference/repl.md" --- # Interactive Robot Framework with `robotcode repl` ::: tip Installation The `robotcode repl` and `robotcode robot-debug` commands come from the optional **`repl`** package. If it isn't installed yet, add it: ```bash pip install robotcode[repl] # or: pip install robotcode[all] ``` ::: Trying out a single Robot Framework keyword usually means more ceremony than the keyword call itself β€” write a `.robot` file with `*** Settings ***` and `*** Test Cases ***` headers, import the right library, run `robot`, open `log.html`, find your test, read the output. For a one-liner you just want to *try*, that's a lot of overhead, and the file lingers in the tree afterwards. **`robotcode repl`** removes the ceremony. It's an interactive shell that runs Robot Framework syntax line by line through the same execution engine as `robotcode robot` β€” same library loading, same variable scoping, same keyword resolution β€” but with no `.robot` file, no boilerplate sections, and no output artefacts unless you ask for them. Type a keyword, press Enter, see the result. State persists across lines within a session, so you can import a library, build up a variable, then call a keyword on it, all without leaving the prompt. Reach for it whenever "let me just *try* it" would be faster than writing a one-off test file β€” library exploration, keyword debugging, environment sanity checks, ad-hoc spikes. `robotcode repl` also has a **command-line debugger** available β€” it starts detached, but once you attach it (`.debug on`, `--debugger-attached`, or by passing `--break …`) a breakpoint that matches a keyword you run at the prompt drops you into a debug prompt with the live call stack, per-frame variables, and a source listing. Its companion command, `robotcode robot-debug`, runs a real `.robot` suite under the same debugger (attached by default). Both are documented in [Command-line debugging](robot-debug.md). **Who this is for:** - **Developers exploring an unfamiliar library** β€” `Import Library SeleniumLibrary`, then start calling keywords and watching what they do, without spinning up a full test. - **Anyone debugging a keyword in isolation** β€” replicate the exact arguments a failing test passes and step through the response without re-running the whole suite. - **Quick spike scripts** β€” try out an XPath, prototype a data-extraction snippet, validate that a library import works in the current environment. - **AI-driven workflows** β€” coding agents (Claude Code, Cursor, Copilot, …) that need to call Robot Framework keywords interactively for test development or library exploration. Piping a snippet through `robotcode repl` is often faster than spawning a full `robot` run and parsing the output. - **Teaching / demos** β€” show a live keyword call with its arguments and assignment without a slide full of `*** Settings ***`. Typical things you can do with it: - import a library and call any of its keywords with arguments - assign and reference variables across multiple lines (state persists for the session) - run control structures (FOR, WHILE, IF, TRY) interactively, multi-line - execute a `.robotrepl` script and either exit or drop into the prompt afterwards - generate a `log.html` / `report.html` / `output.xml` from the interactive session, just like a normal `robot` run - set breakpoints and step through a keyword you run at the prompt β€” or a whole suite via [`robotcode robot-debug`](robot-debug.md) This is intentionally **not** a replacement for writing real test files. It's the lightweight cousin: same engine, immediate feedback, no persistence unless you ask for it. ## Quick start ```bash # Interactive prompt robotcode repl # Execute a REPL script, then exit robotcode repl spike.robotrepl # Execute a REPL script, then drop into the prompt robotcode repl --inspect spike.robotrepl # Pre-set variables for the whole session robotcode repl -v BASE_URL:https://staging.example.com -v RETRIES:3 # Add a directory to the library search path robotcode repl -P ./resources # Capture a log.html / output.xml from the session robotcode repl -d ./repl-output -o output.xml -l log.html ``` To debug a real suite β€” breakpoints, stepping, the call stack β€” see [Command-line debugging](robot-debug.md). ## `repl` and `robot-debug` Two commands: | Command | What it does | | --- | --- | | `robotcode repl` (alias `shell`) | The interactive shell described on this page. Every existing `robotcode repl …` invocation keeps working unchanged. The debugger starts **detached** β€” a failing keyword just prints its error and you stay at the prompt, and nothing pauses. Attach it with `.debug on` (or start with `--debugger-attached`, or pass `--break …`) to make breakpoints, an embedded `Breakpoint`, and failures pause into the `(rdb)` prompt. | | `robotcode robot-debug` (alias `run-debug`) | Runs a real `.robot` suite through the normal runner with the debugger attached. Takes the same arguments as [`robotcode robot`](cli.md#robot) plus the debugger trigger flags. See [Command-line debugging](robot-debug.md). | The shell-specific flags (`-v`, `-P`, `-d/-o/-l/-r/-x`, `--source`, `--inspect`, `--show-keywords`, and `.robotrepl` file arguments) live on `repl`. `robot-debug` instead accepts the full `robotcode robot` option set. The prompt/backend flags (`--backend`, `--plain`, `--no-history`) and the debugger triggers (`--break`, the `--break-on-*` exception flags, and β€” on `robot-debug` β€” `--stop-on-entry`) work on both. ## How the prompt works When stdin is a terminal, `repl` shows the standard Robot Framework prompts: - `>>> ` β€” primary prompt; type a single keyword line and press Enter to execute. - `... ` β€” continuation prompt; appears when you've started a multi-line construct (`FOR`, `WHILE`, `IF`, `TRY`) that's not closed yet. To **exit** the prompt, press Enter on an empty `>>> ` line. `Ctrl-C` clears the current multi-line buffer (or exits if there's no buffer). When stdin is **not a terminal** (piped input, heredoc), prompts are suppressed and the REPL reads input until EOF. That makes it scriptable: ```bash # bash / zsh β€” heredoc, exits when EOF is reached robotcode repl <<'EOF' ${x}= Set Variable 42 Log To Console answer is ${x} EOF # bash / zsh β€” pipe a one-liner printf 'Log To Console hello\n' | robotcode repl ``` ```powershell # PowerShell β€” single-quoted here-string preserves ${x} verbatim @' ${x}= Set Variable 42 Log To Console answer is ${x} '@ | robotcode repl # PowerShell β€” pipe a one-liner 'Log To Console hello' | robotcode repl ``` ## Prompt features Two backends, no platform-specific caveats: - **`prompt-toolkit`** (default) β€” rich line editor with candidate popup, syntax highlighting, signature toolbar, Ctrl-R reverse search, fish-style auto-suggest, multi-line cursor movement, persistent history, fullscreen doc viewer with mouse + search. - **`plain`** β€” basic prompt fallback. No history, no completion, no popup. Active when you select it explicitly (`--plain` / `--backend=plain`), when stdin isn't an interactive terminal (piped input, heredoc, redirected file, CI), or when AI-agent detection falls back to it. ### Picking a specific input backend The REPL uses the `prompt-toolkit` backend by default. Pass `--backend` (or set `ROBOTCODE_REPL_BACKEND`) to force a specific one: | Value | Effect | | ----- | ------ | | `auto` (default) | prompt-toolkit on an **interactive terminal**; on piped/redirected stdin (`echo … \| robotcode repl`, heredocs, CI) β€” or inside a recognised AI agent β€” it falls back to `plain` automatically. | | `prompt-toolkit` | Use the rich editor backend (same as `auto`; explicit form for clarity in scripts). | | `plain` | Bypass the editor layer and fall back to a basic prompt. | #### Disabling all enhancements (AI agents, automation) `--plain` (or `ROBOTCODE_REPL_PLAIN=1`) is a shorthand for `--backend=plain`. It falls back to a basic prompt β€” no history, no completion, no candidate popup, no auto-suggest, no syntax highlighting. Use this for AI-agent invocations or automation pipelines where ANSI escape sequences and completion popups would corrupt stdin/stdout capture. ```bash # AI-agent style: pipe input, capture clean output ROBOTCODE_REPL_PLAIN=1 robotcode repl <<'EOF' Log To Console hello from agent EOF ``` You usually don't need `--plain` for **piped/redirected input or AI agents** β€” the default `auto` backend already falls back to `plain` in those cases (see the table above). Reach for `--plain` to force the basic prompt on an interactive terminal too, or to be explicit in scripts. The agent fallback covers popular environments (Claude Code, Cursor, Copilot CLI, OpenCode, Codex, …); see [AI-agent detection](./ai-agents.md#ai-agent-detection) for the full marker list and the override hatches. Combining `--plain` with a non-`plain` `--backend` value is rejected as a usage error; combining it with `--no-history` is fine (plain mode has no history file anyway). ### History across sessions Available on the prompt-toolkit backend; the plain backend has no history. Every command you press Enter on is saved to a history file. Arrow-up recalls the previous line, `Ctrl-R` runs incremental reverse-search over the whole history β€” same keybindings as bash or Python's own shell. The history file lives in: - `{project_root}/.robotcode_cache/repl_history` when the REPL is launched from inside a project (detected by `robot.toml` / `.robot.toml` / `pyproject.toml` / `.git` / `.hg`) - the per-user cache directory otherwise β€” `~/.cache/robotcode/repl_history` on Linux, `~/Library/Caches/robotcode/repl_history` on macOS, `%LOCALAPPDATA%\robotcode\Cache\repl_history` on Windows - `${ROBOTCODE_CACHE_DIR}/repl_history` if the env var is set β€” overrides both of the above If you upgrade from an earlier build of robotcode whose history file used a different format, the old file is ignored on first read and new entries are written in the current format. The REPL keeps working; you only lose the old history. | Flag / env var | Effect | |---|---| | `--no-history` | Skip loading and saving the history file. In-session arrow-up still works; nothing crosses session boundaries. | | `ROBOTCODE_REPL_NO_HISTORY=1` | Same as `--no-history`, handy when the REPL is launched by a wrapper script. | | `ROBOTCODE_REPL_HISTORY_SIZE=N` | Cap the history at N entries (default: 10000). Each new entry that would push the file past the cap evicts the oldest, so the file stays bounded as you keep using the REPL. | `--no-history` is useful for AI-agent invocations, quick spike sessions, or working with secrets you don't want sitting on disk. ### Tab completion Tab understands Robot's cell-separator semantics (2+ spaces or a tab) and its case-/whitespace-/underscore-insensitive name resolution. The candidates come from the live session, so completions reflect exactly what the REPL would resolve at that point. | Where you press Tab | What you get | |---|---| | At the start of a cell | Keyword names from every loaded library and imported resource | | Inside `${...}` / `@{...}` / `&{...}` | Variables from the live suite scope | | Inside `%{...}` | Environment variables from the process environment | | After `Import Library ` | Library names β€” installed modules (`Coll` β†’ `Collections`), dotted module paths (`robot.libraries.Coll`), filesystem paths (`./libs/My` β†’ `./libs/MyLib.py`) | | After `Import Resource ` | `.robot` / `.resource` files on disk | | After `Import Variables ` | `.py` / `.yaml` / `.yml` / `.json` variable files, plus discoverable variables modules | | After ` =` (RF 7+) | Literal values declared on the argument's type β€” e.g. for a library keyword `my_kw(level: Literal['DEBUG', 'INFO', 'WARN'])`, typing `my_kw level=` shows the three options. Activation rules mirror Robot itself: the name before `=` must be a real positional-or-named / named-only argument of the keyword (or the keyword takes `**kwargs`). Otherwise the cell stays a literal positional value β€” same as Robot's own runtime behaviour. | When the prefix is ambiguous the full candidate list appears on the first Tab press β€” no double-tap, no `Display all NNN possibilities? (y or n)` prompt. ### Multi-line blocks with auto-indent When you open a Robot block construct (`FOR`, `WHILE`, `IF`, `TRY`, `GROUP`), the next continuation line (`... ` prompt) is automatically indented to the matching depth. Nested blocks stack β€” `FOR` inside `IF` inside `FOR` gets three levels. `END` closes the innermost block and the line after it pops one level of indent. ``` >>> FOR ${i} IN RANGE 2 ... Log To Console ${i} # cursor lands here, already indented ... IF ${i} == 1 ... Log inner # two levels deep now ... END ... END ``` On the prompt-toolkit backend you get a real multi-line buffer instead of one prompt per line. Plain **Enter** is *smart*: it submits when your buffer has no open block, otherwise it inserts a newline + auto-indent so you stay inside the block. **Alt-Enter** (`Esc` then `Enter`) and **Ctrl-J** always insert a newline + auto-indent, even when the block is balanced β€” useful when you want to add one more statement before committing. You can also use `Cursor-Up` / `Cursor-Down` to navigate back into earlier lines of the same buffer and edit them. Shift-Enter isn't bound by default: most terminals send the same byte (`\r`) for Shift-Enter as for plain Enter, so a binding would never fire portably. Use Alt-Enter or Ctrl-J β€” both work in every terminal. The plain backend falls back to one prompt per line; the auto-indent still works as a prefill on the next `... ` prompt. ### What the prompt-toolkit backend adds Beyond the basic `plain` prompt, the default backend gives you several extra capabilities: - **Live candidate popup** β€” completions appear *as you type*, in an inline menu under the cursor, with arrow-keys to pick and Enter to accept. No Tab needed (though Tab still works). - **Fish-style auto-suggest** β€” as you type, the rest of the line you typed last time (matching the same prefix) appears greyed-out behind the cursor. Right-arrow accepts it. - **Bracket auto-match**, multi-line cursor movement (up/down inside an open block), `Ctrl-R` reverse search with a dedicated UI. - **Persistent history** β€” see *History across sessions* above. The plain backend has none. The completion popup stays responsive even when there are hundreds of importable modules installed. #### Argument signature in the bottom row When the cursor sits in an argument cell of a recognised keyword, a single status line appears at the bottom of the prompt with the keyword's signature and the active argument highlighted: ``` Log message Β· level='INFO' Β· html=False Β· console=False Β· repr=False ───────── ``` Highlight follows `name=…` syntax: typing `Log msg html=True` lights up `html`, not the positional cell at that index. Falls back to the positional cell index when the name before `=` isn't a real argument of the keyword. The row only shows up when there's a signature to render β€” outside of an argument cell (or for an unrecognised keyword) the prompt has no toolbar at all. #### Documentation hints in the popup Each candidate in the completion popup shows a short context string to its right, so you know *what* a candidate is before picking it: - **Keywords**: the first line of the keyword's docstring (`Log a message with the given level` next to `Log`, etc.). - **Library / resource / variables imports**: the kind of import β€” a built-in library, a third-party library, a `.resource` file, or a Python file discovered on disk. - **Variables (`${…}` / `@{…}` / `&{…}`)**: a truncated preview of the current value in the live suite scope β€” handy when you're trying to remember whether `${COUNT}` is `42` or `"42"`. - **Environment variables (`%{…}`)**: a truncated preview of the environment variable's value. #### Syntax highlighting Coloured Robot syntax is on by default on the prompt-toolkit backend β€” keywords, variables, assigns, comments, block constructs (`FOR`, `IF`, `END`, …) and BDD prefixes (`Given`, `When`, `Then`, … plus localised variants from RF 6+ languages) each get their own colour. Variables decompose to the part level: the sigil and braces, the name, type hints (`${age: int}`), default values (`%{HOME=default}`), subscripts (`${dict}[key]`), nested variables (`${${inner}}`), and inline-Python expressions (`${{expr}}`) all render distinctly. Colours match those used by RobotCode's VS Code extension, so the REPL prompt and the editor share a consistent palette. ### Interactive shortcuts Available on both backends: - **`${_}` β€” last result** β€” like Python's interactive shell. After every keyword call the return value is mirrored into the Robot variable `${_}`, so it always reflects the most recent keyword β€” including keywords that return `None` (e.g. `Log` itself), which set `${_}` to `None`. Use it directly in the next argument: `Evaluate 1 + 2` β†’ `Log ${_}` prints `3`. It's seeded to `None` at startup, so `${_}` resolves even before the first keyword runs. `Ctrl-R` reverse-history search and the argument-signature toolbar are prompt-toolkit-only β€” see *History across sessions* and *Argument signature in the bottom row* above. ### REPL meta-commands Dot-prefixed commands (lines that start with `.`) are handled by the REPL itself β€” they aren't keyword calls, test steps, or log entries. Robot syntax never starts with a dot, so there's no clash with real Robot lines. | Command | Effect | | ----- | ------ | | `.help [cmd]` | Without an argument: list all dot-commands. With an argument: detailed help (usage, flags, examples) for that command β€” e.g. `.help save`. Opens in the doc viewer (see below). | | `.imports` | Show loaded libraries and resource files with their source path and keyword count. | | `.vars [--user]` | Variables in the current scope, name + truncated `repr` of the value. `--user` filters out Robot's internal variables (`${OUTPUT_DIR}`, `${SUITE_NAME}`, …). | | `.kw [name-or-text]` | Keyword documentation in the doc viewer β€” signature, argument table (types + defaults), tags, docstring body. Same renderer the editor's hover uses. Bare `.kw` lists all loaded keywords; with non-matching text it lists keywords whose name contains it. | | `.doc ` | Full library or resource documentation in the doc viewer β€” version + scope, introduction (with the auto-linked Table of Contents), every keyword with its own signature + arguments + body. Only libraries and resources the current session has **imported** can be shown, addressed by their namespace name (for a library imported with `AS` / `WITH NAME`, the alias; for a resource, the file name without extension). | | `.history [N]` | Show the last N entries (default 20), numbered. Available on the prompt-toolkit backend; plain backend has no history. | | `.history clear` | Truncate the in-memory history and the persistent history file. | | `.history del ` | Drop the single entry at index N from both. | | `.cwd` | Print the current working directory (where relative paths in imports resolve from). | | `.clear` | Erase the screen. | | `.save [-a] [-t NAME] ` | Export the session as a runnable `.robot` file (see below). | | `.exit` / `.quit` | Leave the REPL β€” equivalent to `Ctrl-D` on an empty prompt. | `.kw` and `.doc` show the same documentation the editor displays on hover β€” full per-keyword pages with signature, argument table (types + defaults), tags, and docstring body. It's rendered as styled Markdown, so headings, lists, code blocks, tables, and inline emphasis show up formatted in any modern terminal. #### The doc viewer `.help`, `.kw`, `.doc` (and `F1`, which is the keyboard shortcut for `.help`) open the rendered output in a fullscreen viewer (like `less`, `man`, or `vim`). Your prompt and scrollback are untouched: when you close the viewer the terminal snaps back to exactly where you were. | Key | Effect | | --- | ------ | | `j` / `↓` / Mouse wheel down | Scroll one line down | | `k` / `↑` / Mouse wheel up | Scroll one line up | | `PgDn` / `Ctrl-D` / `Space` | Scroll one page down | | `PgUp` / `Ctrl-U` / `b` | Scroll one page up | | `g` / `Home` | Jump to top | | `G` / `End` | Jump to bottom | | `/` | Open search input | | `n` / `N` | Next / previous search match | | `Tab` / `Shift-Tab` | Cycle through links in the current viewport | | `f` / `Enter` (on a focused link), mouse click | Follow link β€” `#anchor` scrolls to the section, `http(s)://` opens in your browser | | `[` / `]` | Browser-style back / forward through anchor follows | | `Shift` + drag | Native terminal text selection (mouse capture is suspended while Shift is held) | | `q` / `Esc` / `Enter` (with no link focused) | Close the viewer | Search is case-insensitive substring. The current match is highlighted in reverse; `n`/`N` walk through all matches and scroll them into view. Link cycling skips back to the user's current scroll position if you've scrolled away, so `Tab` always lands on something you can see. On the plain backend the doc-display commands still work β€” they print the rendered markdown through the pager with no colour, no fullscreen overlay. Useful in AI-agent sessions and headless environments where a fullscreen overlay would get in the way. ### Saving a session as a runnable `.robot` file `.save scratch.robot` writes the inputs you typed (the ones that round-tripped through Robot's parser without errors) to a `.robot` file you can re-run with `robot scratch.robot`: ``` robotcode repl >>> Import Library Collections >>> ${d}= Create Dictionary a=1 b=2 >>> Log ${d}[a] 1 >>> .save scratch.robot Wrote scratch.robot (3 entries) >>> .exit $ robot scratch.robot ``` The exporter does two things automatically: - **Hoists imports.** `Import Library / Resource / Variables` calls in the session move to a `*** Settings ***` section as `Library / Resource / Variables `. - **Wraps the body** in a single `*** Test Cases ***` block named `REPL Session `. Override the name with `-t MyTest`. `-a` appends to an existing file instead of overwriting, so you can build a test suite incrementally across multiple REPL sessions. Failed entries β€” anything Robot's parser rejected β€” are silently skipped, so the exported file always parses cleanly. One caveat: REPL-only variables such as `${_}` parse fine but don't exist in a standalone `robot` run, so a session that relied on them may need a small edit before the exported file runs on its own. ## What syntax the REPL accepts The REPL treats each input as a **test-case body** β€” the lines you'd write inside `*** Test Cases ***`. So you can use: - keyword calls with positional and named arguments - variable assignment (`${x}= Set Variable 42`) and references (`Log ${x}`) - multi-line control structures (`FOR`, `WHILE`, `IF` / `ELSE IF` / `ELSE`, `TRY` / `EXCEPT` / `FINALLY`, `GROUP`) - inline `VAR ${name} value scope=GLOBAL` statements - `Import Library LibraryName arg1 arg2` to add libraries during a session - `Import Resource path/to/resource.robot` to bring user keywords into scope What you **can't** type at the prompt: - `*** Settings ***` / `*** Test Cases ***` / `*** Keywords ***` headers β€” the REPL is already inside a test body. Use `Import Library` / `Import Resource` instead of a `Settings` section, and put reusable keywords in a `.resource` file that you import. - Defining new user keywords inline β€” same reason. Put them in a `.resource` file and import it. - `*** Test Cases ***`-level metadata (`[Tags]`, `[Setup]`, `[Teardown]`, …) β€” the REPL session is one synthetic test; per-test metadata doesn't apply. ## State persists across lines Variables, library imports, and the suite's variable scope all carry over from one prompt line to the next. So this works: ``` >>> ${greeting}= Set Variable Hello >>> Log To Console ${greeting}, world! Hello, world! >>> Import Library Collections >>> ${items}= Create List apple banana cherry >>> Log To Console ${items} ['apple', 'banana', 'cherry'] ``` Variables behave the way they would inside a single test case. ## Loading libraries and resources `BuiltIn` is the only library available out of the box (same as a normal Robot run). Everything else β€” `Collections`, `OperatingSystem`, `SeleniumLibrary`, your own libraries β€” needs an explicit import: ``` >>> Import Library SeleniumLibrary >>> Import Library OperatingSystem >>> Import Resource ./resources/common.resource ``` The Settings-style `Library` / `Resource` / `Variables` also work at the prompt β€” they're **REPL-only aliases** for `Import Library` / `Import Resource` / `Import Variables`, so `*** Settings ***` muscle memory just works (`Library Browser timeout=20s AS B`). Both spellings are fine, they show up in tab-completion, and `.save` records either as the matching `Settings` line. If your libraries live in a directory that isn't on `sys.path`, add it with `-P` at startup: ```bash robotcode repl -P ./libs -P ./vendor/python-libs ``` `-P` accepts the same `PATH` strings as `robot --pythonpath`. > **Heads-up for Robot Framework < 7.4.** Bare relative paths in the BuiltIn import keywords `Import Resource` / `Import Library` / `Import Variables` (e.g. `Import Resource foo/my.resource`) only resolve against the directory of the importing file starting with RF 7.4. On older RF versions these keywords look the path up via the module search path only, so a bare relative form will fail with `Resource file '…' does not exist.` On those versions, either prefix the path with `${CURDIR}/` (e.g. `Import Resource ${CURDIR}/foo/my.resource`) or put the directory on the module search path. On RF 7.4+ the bare form just works. ## Pre-seeding variables Variables can be set up before the prompt opens: | Flag | Effect | |---|---| | `-v NAME:VALUE` | Equivalent to `robot --variable NAME:VALUE`. Repeatable. | | `-V PATH` | Equivalent to `robot --variablefile PATH`. Loads `.py`, `.yaml`, or `.json` files. Repeatable. | ```bash robotcode repl -v BASE_URL:https://staging.example.com -V ./creds.yaml ``` Once inside, the variables are accessible like any other: ``` >>> Log To Console ${BASE_URL} https://staging.example.com ``` You can also define variables inline via the `VAR` statement (RF 7+) or classic assignment. ## Running REPL scripts Pass one or more **REPL scripts** to execute their content before the prompt. Each is read as a **test-case body** β€” the same syntax as the prompt itself: just keyword calls and control structures, one entry per line. These scripts conventionally use the `.robotrepl` (or `.robotscript`) extension, which the RobotCode VS Code extension highlights as REPL input. > **These are REPL scripts, not full `.robot` suites.** Because the content runs as the body of a single implicit test, section headers like `*** Settings ***` or `*** Test Cases ***` are **not** allowed β€” a file containing them fails with `No keyword with name '*** Settings ***' found`. Import libraries and resources from inside the body with the `Import Library` / `Import Resource` keywords instead of a Settings section. ```bash robotcode repl setup.robotrepl # execute, then exit robotcode repl setup.robotrepl more.robotrepl # multiple files, in order, then exit robotcode repl --inspect setup.robotrepl # execute, then drop into the prompt ``` With `--inspect`, the file runs the same way but, instead of exiting, leaves you at `>>>` with everything it set up still in scope β€” variables, plus any libraries or resources imported via `Import Library` / `Import Resource`. Handy for inspecting the state a long setup sequence produced without rerunning it each time. ## Capturing the session as a Robot run By default, `repl` runs everything in-process and discards the report. The standard `robot`-style output flags work here too, with the same names: | Flag | Effect | |---|---| | `-d, --outputdir DIR` | Directory for any output files. | | `-o, --output FILE` | Write `output.xml`. | | `-l, --log FILE` | Write `log.html`. | | `-r, --report FILE` | Write `report.html`. | | `-x, --xunit FILE` | Write a JUnit-style `xunit.xml`. | ```bash robotcode repl -d ./repl-output -o output.xml -l log.html ``` After the session ends (you press Enter on an empty prompt or `EOF` arrives), the output files are written and you can feed them right back to `robotcode results`: ```bash robotcode repl -d ./tmp -o output.xml # … type a few keyword calls … robotcode results log -o ./tmp/output.xml ``` Useful when you're prototyping a sequence of keywords and want to attach the resulting `log.html` to a bug report or an issue comment. ## `--source` for working-directory context ```bash robotcode repl --source ./tests/login_spike.robot ``` `--source FILE` does **one** thing: it uses the parent directory of `FILE` as the REPL session's working directory. Relative paths in `Import Resource`, `Import Library`, file-based variables, etc. then resolve against that directory β€” handy when you're prototyping a snippet that will eventually live in a real test file and want the import paths to behave the same way. The file itself is never read or written, so the path doesn't have to exist. If you only care about the directory, point at any (real or imagined) filename inside it: ```bash robotcode repl --source ./tests/_.robot ``` ## Tracing executed keywords ```bash robotcode repl --show-keywords ``` `-k / --show-keywords` prints a `KEYWORD . arg1 arg2` line for every keyword the REPL dispatches, before the keyword's own output. Useful when you suspect the wrong keyword is being resolved (e.g. a name collision between two libraries, or a user keyword shadowing a library keyword): ``` >>> Log To Console hi KEYWORD BuiltIn.Log To Console hi hi ``` ## Debugging at the prompt The same debugger that powers [`robotcode robot-debug`](robot-debug.md) is available in the interactive shell, but it starts **detached**: nothing pauses, and a failing keyword just prints its error and leaves you at the `>>>` prompt. **Attach it** to make breakpoints, an embedded `Breakpoint` keyword, and failures drop you into the `(rdb)` debug prompt: - `.debug on` attaches at the prompt; `.debug off` detaches again; bare `.debug` shows the current state. - `--debugger-attached` attaches from the start. - Passing a pause trigger (`--break`, a `--break-on-*` flag) attaches automatically, so `robotcode repl --break "Submit Login"` just works. Detaching is non-destructive: your breakpoints and `.catch` exception filters (see [Exception breakpoints](robot-debug.md#exception-breakpoints)) stay configured, so `.debug on` resumes with the same setup. Attaching also arms the default uncaught-failure break, so an attached session pauses on *any* uncaught failure (a typo, a `Fail`), not just your breakpoint β€” add `--no-break-on-exception` to keep only the explicit breakpoint. ```bash # Pause on "Submit Login" β€” auto-attaches, so uncaught failures pause too robotcode repl --break "Submit Login" # ...but only on the breakpoint, not on every failure robotcode repl --break "Submit Login" --no-break-on-exception # Start with the debugger attached (breaks on an uncaught failure by default) robotcode repl --debugger-attached ``` To debug a **real `.robot` suite** β€” and for the full reference on breakpoints, stepping, the call stack, inspecting variables, and the complete debug command set β€” see [Command-line debugging with `robotcode robot-debug`](robot-debug.md). ## Recipes ```bash # Explore a library's API live robotcode repl >>> Import Library Browser >>> ${cat}= Get Library Instance Browser >>> Log ${cat} … inspect the instance, try keywords on it … # Replicate the exact arguments a failing test passes to a keyword robotcode repl -v USER:alice -v PASS:s3cr3t >>> Import Resource ./resources/login.resource >>> Login With Credentials ${USER} ${PASS} # Prototype a keyword sequence and capture a log.html for review robotcode repl -d /tmp/probe -o output.xml -l log.html # CI smoke check β€” pipe a sequence through stdin, exit non-zero on failure # bash / zsh printf 'Run Keyword And Expect Error * Fail sanity\n' \ | robotcode repl # Validate a YAML/Python variable file loads correctly robotcode repl -V ./vars.yaml >>> Log To Console ${SOME_KEY_FROM_VARS} # Run a REPL script then poke at the resulting state robotcode repl --inspect ./scratch/setup_world.robotrepl ``` ```powershell # CI smoke check on Windows / PowerShell 'Run Keyword And Expect Error * Fail sanity' | robotcode repl # Multi-line input through a here-string @' ${BASE_URL}= Set Variable https://staging.example.com Log To Console pinging ${BASE_URL} '@ | robotcode repl ``` ## What it isn't - **Not a Python REPL.** It's keyword-driven, not expression-driven. Type Robot Framework syntax, not Python. - **Not a *graphical* debugger.** `robot-debug` is a *command-line* debugger (see [Command-line debugging](robot-debug.md)). For step-debugging inside the editor β€” gutter breakpoints, a Variables pane, the call-stack view β€” use the **RobotCode** VS Code extension's debugger. - **Not a way to define new user keywords.** Those go in `.resource` files; the REPL imports them. - **Not persistent.** Closing the prompt throws away the session unless you've passed `-o` / `-l` / `-r` / `-x` to capture artefacts. For the per-flag reference of the base `repl` options see the auto-generated [CLI reference](cli.md#repl). --- URL: "/03_reference/robot-debug" LLMS_URL: "/03_reference/robot-debug.md" --- # Command-line debugging with `robotcode robot-debug` ::: tip Installation The `robotcode robot-debug` command (and the `robotcode repl` shell) come from the optional **`repl`** package. If it isn't installed yet, add it: ```bash pip install robotcode[repl] # or: pip install robotcode[all] ``` ::: `robotcode robot-debug` is a `pdb`-style **command-line debugger** for Robot Framework. It runs a real `.robot` suite through the same runner as [`robotcode robot`](cli.md#robot), but pauses at breakpoints β€” a `file:line`, a keyword name, an embedded `Breakpoint` keyword, or the first uncaught failure β€” and drops you into a debug prompt with the live call stack, per-frame variables, a source listing, and the ability to run any keyword in the paused context. There are two ways in: - **`robotcode robot-debug`** (alias `run-debug`) runs a real `.robot` suite through the normal runner with the debugger attached. It takes the same options and arguments as [`robotcode robot`](cli.md#robot) β€” paths, `--variable`, `--include`, profiles, … β€” plus the trigger flags below. - **[`robotcode repl`](repl.md)** (the interactive shell) has the *same* debugger available β€” though it starts **detached**, so attach it (`.debug on` or `--debugger-attached`) to have a breakpoint that matches a keyword you run at the prompt drop you into the debug prompt too. The debugger sees every keyword and control-structure (FOR / IF / TRY / WHILE / …) start and end, on every supported Robot Framework version (5.0 – 7.x). For graphical step-debugging inside the editor, use the VS Code extension instead β€” see [Relationship to the VS Code debugger](#relationship-to-the-vs-code-debugger). **Who this is for:** - **Developers debugging a failing test or suite** β€” pause exactly where it breaks and inspect the live call stack and per-frame variables, instead of sprinkling `Log` statements and re-running. - **Anyone chasing an intermittent or hard-to-reproduce failure** β€” the first uncaught failure pauses the run out of the box, so you catch the state at the moment it actually goes wrong. - **Terminal, SSH, container, and headless users** β€” full step-debugging where a graphical editor and a DAP client aren't available, driven entirely from the command line. - **CI and scripted debugging** β€” feed the debug prompt a fixed sequence of commands from a pipe or file (`.where`, `.vars`, `.continue`) to capture state non-interactively, or reproduce a CI failure locally with the same breakpoints. - **AI-driven debugging** β€” coding agents (Claude Code, Cursor, Copilot, …) can drive the debugger non-interactively: set a breakpoint, then pipe `.where` / `.vars` / `.print` to capture the paused call stack and variables and reason about a failure instead of guessing. Inside a recognised agent the prompt falls back to the plain backend automatically, so the captured output stays clean. ## Quick start ```bash # A run pauses at the first uncaught failure out of the box robotcode robot-debug tests/ # Pause at a specific line, then step and inspect robotcode robot-debug --break login.robot:42 tests/ # Pause at the very first keyword of a run robotcode robot-debug --stop-on-entry tests/login.robot # Combine line + keyword breakpoints robotcode robot-debug --break login.robot:42 --break "Submit Login" tests/ ``` `robot-debug` accepts the full `robotcode robot` option set (see the [CLI reference](cli.md#robot)) plus the debugger triggers below. The prompt/backend flags (`--backend`, `--plain`, `--no-history`) work here too β€” see [Prompt features](repl.md#prompt-features). The interactive shell's setup flags (`-v`, `-P`, output flags, `--source`, …) live on [`robotcode repl`](repl.md), not here. ## Setting breakpoints There are several ways to make a run pause; they combine freely. | Trigger | How | | --- | --- | | **Line breakpoint** | `--break path/to/test.robot:42` β€” pause when execution reaches that line. Repeatable. | | **Keyword breakpoint** | `--break "Open Browser"` β€” pause whenever a keyword with that name is about to run. Repeatable. | | **Embedded `Breakpoint` keyword** | Add `Breakpoint` as a step in your `.robot` / `.resource` (after `Library robotcode.repl.Repl`). It's a no-op when run normally and a hard breakpoint under the debugger β€” no flag needed. | | **Stop on entry** | `--stop-on-entry` (`robot-debug` only) β€” pause at the very first keyword. | | **Uncaught exception** | Pause at an uncaught failing keyword (not caught by `TRY`/`EXCEPT` or `Run Keyword And …`), *before* the failure unwinds. **Armed by default**, but it only fires while the debugger is attached β€” so it triggers out of the box under `robot-debug`, while the interactive `repl` (detached by default) just prints the error until you attach with `.debug on` / `--debugger-attached`. Disarm the filter with `--no-break-on-exception`. | | **Every exception** | `--break-on-all-exceptions` β€” pause at *every* failing keyword, even ones caught by `TRY`/`EXCEPT` or `Run Keyword And …`. | | **Failing test / suite** | `--break-on-failed-test` / `--break-on-failed-suite` β€” pause at the end of a failing test / suite. | A **keyword breakpoint** matches by exact name β€” either the bare keyword name (`--break "Open Browser"`) or its fully-qualified `Library.Keyword` form (`--break "SeleniumLibrary.Open Browser"`, to disambiguate a name two libraries share). Unlike Robot's own keyword lookup, the match is case- and whitespace-sensitive, so spell it as it appears in the run. The exception breakpoints are armed on both `repl` and `robot-debug` (`--break-on-exception` on by default, `--no-break-on-exception` to disarm), but they only pause **while the debugger is attached**. `robot-debug` is attached out of the box; the interactive `repl` starts detached β€” a failing keyword just prints its error β€” until you attach with `.debug on` or `--debugger-attached`. (Conversely, `robotcode robot-debug --no-debugger-attached` runs the suite straight through without ever pausing β€” the same as `robotcode robot`.) Adjust the active exception filters at runtime with `.catch`, and attach/detach with `.debug` (see [Exception breakpoints](#exception-breakpoints) below). ```bash # Triggers combine, and the default can be turned off: # pause at the end of failing tests, but not on uncaught failures robotcode robot-debug --break-on-failed-test --no-break-on-exception tests/ ``` You can also add and remove breakpoints from the debug prompt at runtime with `.break` / `.tbreak` / `.delete` / `.disable` (see below). ### The embedded `Breakpoint` keyword To pause at a fixed spot without passing `--break` on every run, put a `Breakpoint` step directly in your `.robot` or `.resource` file. Import the marker library once, then call `Breakpoint` wherever you want execution to stop: ```robot [login.robot] *** Settings *** Library robotcode.repl.Repl *** Test Cases *** Login Open Browser ${URL} Breakpoint # the run pauses here under the debugger Input Text id=user ${USER} Submit Login ``` `Breakpoint` is a **no-op in a normal `robot` run** β€” the suite executes straight through it β€” and a **hard breakpoint** whenever the debugger is attached, whether through `robotcode robot-debug` or a keyword you run at the `robotcode repl` prompt. You can leave it in the file while iterating; it only bites when you're actually debugging, and it needs no `--break` flag. `Breakpoint` is the only keyword from `robotcode.repl.Repl` meant for your own suites β€” `Repl` and `Exit` are used internally and aren't called by hand. > **Plain backend for non-interactive runs.** On an interactive terminal the debug prompt gives you completion, history, and highlighting at the stop. When you feed it from a pipe, a script, or CI, the default `auto` backend falls back automatically to a plain prompt (or pass `--plain` explicitly). See [Picking a specific input backend](repl.md#picking-a-specific-input-backend). ## At a stop When the run pauses, the debugger prints a one-line banner and opens a prompt: ``` * breakpoint Submit Login (login.robot:42) (rdb) ``` The banner is `* (:)`, where reason is `breakpoint`, `step`, `entry`, `pause`, or `exception`. At the `(rdb)` prompt you have the full debug command set (below) **plus** every shell command (`.kw`, `.doc`, `.vars`, …), and you can run any keyword in the paused context β€” its result is echoed and any variable it assigns stays in scope, exactly like at the shell prompt. `robot-debug` produces the **same console output as `robotcode robot`** β€” the run is fully visible, and continuing or stepping shows execution proceeding. The debug prompt is simply interleaved with Robot's live console at each stop; when a test happens to finish right at a prompt its `| PASS |` marker lands next to the prompt, which is cosmetic. (Use `.detach` at the prompt to let the rest of the run finish and print normally.) ## Debug commands Each command has a canonical long name and, where it helps, a single-letter shortcut; long names also accept any unambiguous prefix (`.bre` β†’ `.break`). At the *shell* prompt, where there is no active stop, the navigation/resume commands simply report `not at a breakpoint`. **Stepping and resuming** | Command | Effect | | --- | --- | | `.continue` / `.c` | Resume until the next breakpoint, stop, or the end of the run. | | `.step` / `.s` | Step into: stop at the next keyword, descending into calls. | | `.next` / `.n` | Step over: stop at the next keyword in the current frame. | | `.return` / `.r` | Continue until the current keyword returns, then stop. | | `.until` | Continue until a *later* line in the current frame β€” past a loop's remaining iterations β€” or until the frame returns. | **Stack and frames** | Command | Effect | | --- | --- | | `.where` / `.w` | Show the call stack β€” innermost frame is `#0`, `>` marks the selected one. | | `.up` / `.u` | Select the calling (outer) frame. | | `.down` / `.d` | Select the called (inner) frame. | | `.frame N` / `.f N` | Select frame number N directly (`#0` is the innermost). | **Inspecting** | Command | Effect | | --- | --- | | `.list` / `.l` | Show the source at the current stop. On prompt-toolkit: the whole file in the scrollable viewer, scrolled to the current line (marked `->`). On the plain backend: a Β±5-line inline window. | | `.source ` | Show a keyword's source. On prompt-toolkit: the **whole file** in the scrollable viewer, opened at the definition line (marked `->`). On the plain backend: inline from the definition downward β€” 10 lines, or `.source ` for `n`. | | `.print ` / `.p` | Evaluate a variable or expression in the selected frame and print the result. | | `.pprint ` / `.pp` | Same, but pretty-printed β€” readable for nested dicts / lists. | | `.whatis ` | Print the Python type of a variable or expression. | | `.vars` / `.v` | Show the variables in scope (Local / Test / Suite / Global), name + value. `--user` skips Robot internals. | | `.set ${x} ` | Set a **scalar** variable in the selected frame's local scope (the value is variable-substituted, like `Set Variable`). List/dict variables (`@{…}`/`&{…}`) and item access (`${x}[0]`) aren't supported. | | `.display ` | Show ``'s value automatically at every following stop. Bare `.display` lists/shows the registered expressions. | | `.undisplay ` | Stop displaying ``; bare `.undisplay` clears the list. | You can also just type a keyword at the `(rdb)` prompt to run it in the paused context, exactly like at the shell prompt. `.source` resolves keywords from imported libraries and resources. A keyword defined directly in the suite file currently being run is *not* resolvable by name; when you're stopped inside one, use `.list` to see its source at the current line. **Breakpoints** | Command | Effect | | --- | --- | | `.break [, ]` / `.b` | Add a breakpoint β€” `file:line` or a keyword name, optionally conditional (`.break Login, ${retries} > 3`). | | `.tbreak [, ]` | Same, but one-shot: removed after it first stops. | | `.breakpoints` / `.bp` | List the breakpoints, numbered, with their attributes and the active exception filters. | | `.condition ` | Set a condition on breakpoint `` (bare `.condition ` clears it). | | `.ignore ` | Skip breakpoint ``'s next `` hits. | | `.delete ` | Remove breakpoint ``; bare `.delete` removes all. | | `.disable ` / `.enable ` | Turn breakpoint `` off / on; bare form applies to all. | | `.commands ` | Attach debugger commands to breakpoint ``, replayed at each hit (enter one per line, end with `end`; a leading `silent` suppresses the banner; a resuming command lets the run continue automatically). | Breakpoints are referenced by the stable number shown in `.breakpoints`. A **condition** is evaluated in the stopped frame each time the breakpoint is reached; if the expression itself raises, the debugger stops anyway so the breakage is visible. `.ignore` skips the next *N* triggering hits. **Logpoints β€” log and continue.** There's no dedicated logpoint command, but you get the "print a value on every hit, never stop" effect by attaching commands to a breakpoint: a leading `silent` suppresses the banner and a trailing resuming command (`.continue`) carries on without prompting. ``` (rdb) .break Process Item Breakpoint 1 at keyword 'Process Item' (rdb) .commands 1 Enter commands for breakpoint 1, one per line; `end` to finish: (com) silent (com) .print ${item} (com) .continue (com) end Breakpoint 1: 3 command(s) ``` Now every hit on `Process Item` prints `${item}` and runs on without pausing. (Graphical gutter logpoints are a feature of the VS Code / DAP debugger; in the CLI, `.breakpoints` shows a `logpoint` flag for any breakpoint that carries one.) **Exception breakpoints** | Command | Effect | | --- | --- | | `.catch uncaught` | Pause at uncaught keyword failures (same as `--break-on-exception`). | | `.catch all` | Pause at *every* keyword failure, even ones caught by `TRY`/`EXCEPT` or `Run Keyword And …`. | | `.catch test` / `.catch suite` | Pause at a failing test end / suite end. | | `.catch off` | Clear all exception breakpoints. Bare `.catch` shows what's armed. | | `.debug on` / `.debug off` | Attach / detach the debugger β€” the master switch over *all* pausing (breakpoints, stepping, and exception breaks). Detaching keeps your breakpoints and `.catch` filters configured, so `.debug on` resumes with the same setup; bare `.debug` shows `attached` / `detached`. | The CLI flags set the *initial* filters β€” `--break-on-exception` ↔ `.catch uncaught`, `--break-on-all-exceptions` ↔ `.catch all`, `--break-on-failed-test` ↔ `.catch test`, `--break-on-failed-suite` ↔ `.catch suite` β€” and `.catch` adjusts them at runtime. The filters are armed by default but only pause **while the debugger is attached**: `robot-debug` is attached out of the box, while the interactive `repl` starts detached (attach with `.debug on` or `--debugger-attached`). **Ending the session** | Command | Effect | | --- | --- | | `.detach` | Detach and let the run finish without stopping again β€” like `.debug off` then `.continue` in one step. Your breakpoints and `.catch` filters are kept, so you can re-arm pausing later with `.debug on`. | | `.abort` | Abort the run immediately and exit (no further keywords, no reports). | At a stop, `.exit` / `.quit` (which leave the *shell*) would be ambiguous, so they point you at `.continue` / `.detach` / `.abort` instead of quitting. `Ctrl-C` or `Ctrl-D` at the `(rdb)` prompt **resumes the run** β€” the same as `.continue`, not a kill β€” so use `.abort` when you actually want to stop it. Pressing Enter on an empty line does nothing and just re-prompts (unlike the shell's `>>>` prompt, where an empty line exits). ## A debug session, end to end ``` $ robotcode robot-debug --break "Greet" hello.robot * breakpoint Greet (hello.robot:11) (rdb) .list 6 Log hello 7 8 *** Test Cases *** 9 T 10 Log start -> 11 Greet 12 Log end (rdb) .where > #0 Greet hello.robot:11 #1 T hello.robot:9 #2 Hello hello.robot (rdb) .print ${name} ${name} = 'world' (rdb) Log debugging ${name} [ INFO ] debugging world => None (rdb) .continue ``` Typing a keyword at the prompt runs it in the paused context: its log output appears (`[ INFO ] …`) and the `=> ` line echoes the keyword's return value (`None` for `Log`). ## Recipes ```bash # Debug a failing suite: pauses at the first uncaught failure out of the box robotcode robot-debug tests/login.robot # … at (rdb): .where, .vars, .print ${response}, .up, .continue … # Stop at a keyword, drive the debug prompt from a script (plain backend) printf '.where\n.vars\n.continue\n' \ | robotcode robot-debug --plain --break "Submit Login" tests/ # Same robot options as a normal run β€” variables, tag filters, … β€” plus debugging robotcode robot-debug -v ENV:staging --include smoke tests/ # Set a conditional breakpoint interactively, then run robotcode robot-debug --stop-on-entry tests/orders.robot # … at (rdb): .break Process Item, ${index} == 7 then .continue ``` ## Relationship to the VS Code debugger This is the **command-line** debugger. For graphical step-debugging inside the editor β€” breakpoints in the gutter, a Variables pane, the call-stack view β€” use the **RobotCode** VS Code extension's debugger, which speaks the Debug Adapter Protocol. Both pause Robot Framework runs; the CLI debugger is the terminal-native, scriptable counterpart. The shared shell features β€” the prompt backends, history, tab completion, the doc viewer, and the dot-command set you also get at a stop β€” are documented on the [`robotcode repl`](repl.md) page. For the per-flag reference of the underlying `robot` options see the [CLI reference](cli.md#robot). --- URL: "/04_tip_and_tricks" LLMS_URL: "/04_tip_and_tricks.md" --- # Tips and Tricks Welcome to the RobotCode Tips and Tricks section! This part of the documentation is designed to help you optimize your workflow, solve common problems, and discover useful techniques that may not be immediately obvious. ## Introduction Whether you're a beginner or an experienced robot programmer, this collection of tips and tricks aims to enhance your productivity and help you get the most out of RobotCode. The suggestions here come from real-world experience and community contributions. ## Contents - [Avoiding a Global Resource File](./01_avoiding_a_global_resource_file.md) While global resource files might seem convenient initially, they lead to circular dependencies, keyword ambiguities, performance issues, and maintenance challenges. This guide explains the problems of this approach and offers a modular alternative that improves code organization, maintainability, and performance. - [Why is my variable shown as "not found"](./02_why_variable_not_found.md) This guide explains the common reasons for `VariableNotFound` errors in RobotCode and offers practical solutions. - [Customizing Visual Studio Code for using RobotCode](./03_vscode_customizations.md) This guide helps you customize VSCode to improve your experience when working with RobotCode. ## Contributing Have a useful tip or trick? Consider contributing to this section! Your experience might help other members of the RobotCode community. --- *Note: This documentation is continuously evolving. Check back regularly for new tips and tricks.* --- URL: "/04_tip_and_tricks/01_avoiding_a_global_resource_file" LLMS_URL: "/04_tip_and_tricks/01_avoiding_a_global_resource_file.md" --- # Avoiding a Global Resource File ## Introduction In many Robot Framework projects, there is a temptation to simplify setup by consolidating all resources and libraries into one global fileβ€”often named something like `Keywords.resource`β€”which is then usually the only resource imported into suites and other resource files. **Executive Summary**: While global resource files might seem convenient initially, they lead to circular dependencies, keyword ambiguities, performance issues, and maintenance challenges. This guide explains the problems of this approach and offers a modular alternative that improves code organization, maintainability, and performance. ## Why This Approach is Problematic - **Circular Dependencies:** Using one global file in multiple keyword resource files can create circular dependencies. While Robot Framework does not display warnings during execution, RobotCode flags these issues with warnings about already imported files or circular references. These warnings highlight poor design practices that complicate dependency management, hinder refactoring, and reduce modularity. Tightly coupled components can lead to cascading errors when changes are made. - **Ambiguities in Keyword Resolution and Variable Precedence:** In Robot Framework, keywords are not silently overwritten. Instead, if multiple keywords with the same name are present, test execution fails due to ambiguous matches. This forces test writers to explicitly decide which resource's keyword to use, thereby increasing the effort during test case creation. Additionally, variables behave differently: the first variable declaration takes precedence, and all subsequent declarations in other variable sections from different resource files are ignored. Consequently, when using a global resource file, you must carefully manage the order in which resources are imported to ensure the intended variable values are usedβ€”further adding to the overall complexity. - **Performance Issues:** For every keyword call, Robot Framework iterates through the entire list of known keywordsβ€”and code analysis tools like RobotCode must do the same. The performance impact significantly depends on whether the system checks 50, 500, or even 5000 keywords; indeed, 500 to 5000 keywords is a realistic number in an average project. This process is especially time-consuming with embedded arguments that require regular expressions rather than simple string comparisons. A large global file filled with rarely used elements can significantly slow down keyword resolution, particularly in larger projects. *Heuristic:* If a global resource file contains more than ~200 keywords or imports more than ~20 resource files, consider modularizing to improve performance and maintainability. - **Decreased Maintainability:** While the number of resource files may be relatively smallβ€”perhaps 50 to 100β€”the combined global resource file can easily contain 500 or more keywords. This consolidation makes it difficult for test writers to quickly locate the relevant keyword or variable among hundreds of entries. The dense aggregation reduces clarity and increases the maintenance burden, as even a small change might affect multiple areas of the project. Refactoring becomes more challenging when the entire functionality is bundled into a single file, since updates or corrections must be made with care to avoid unintended side effects across the project. - **Creation of Unnecessary References:** Relying on a centralized file forces all suites and resource files to reference the same global file, even if they only need a subset of its contents. This means that every suite is indirectly coupled to every keyword and variable in that file, regardless of whether they are used. Such an arrangement makes it difficult to determine which keywords are actually needed for a given suite. When updates or refactoring are required, developers may unintentionally modify or remove elements that other parts of the project still depend on. This extra layer of indirection complicates resource tracking, increases the likelihood of errors during maintenance, and can create confusion in larger teams where multiple developers modify the global file simultaneously. ### Example of Problematic Global Resource File Consider this example of a typical global resource file that causes issues: ```robot *** Settings *** # Global.resource - tries to do everything Library SeleniumLibrary Library RequestsLibrary Library DatabaseLibrary Library OperatingSystem Resource LoginKeywords.resource Resource CustomerKeywords.resource Resource OrderKeywords.resource Resource ApiKeywords.resource Resource ReportingKeywords.resource # ...and 20+ more imports *** Variables *** ${GLOBAL_URL} https://example.com ${DB_CONNECTION} connection_string # ...hundreds of variables for different modules *** Keywords *** # 500+ keywords covering every aspect of the system ``` Note: importing the same library or resource with different parameters in different places can lead to earlier instances being reused or overwritten, causing surprising behavior. Avoid parameterized duplicates and prefer small, purpose-specific imports. When this file gets imported into multiple other resources and suite files, it creates a tangled web of dependencies. ## Documenting with Suite Settings Suite settings do more than just configure your test environmentβ€”they serve as essential documentation for your project. When you explicitly declare libraries, resources and also variables in your settings section, you're creating a clear record of which technical or functional areas of the application are being used in this file. This transparency helps team members, stakeholders, and testers quickly understand the suite's purpose. For example: ```robot *** Settings *** Library LoginProcess Resource CustomerManagement.resource Resource DatabaseValidation.resource ``` This declaration immediately communicates that this suite deals with login processes, customer management, and database validationβ€”improving maintainability and knowledge transfer within your team. ## Limitations in Import and Package Management Robot Framework’s import mechanism is quite basicβ€”it lacks namespaces or similar constructs found in other programming languages. Instead, it relies solely on a name alias for libraries or the resource file name. Although Robot Framework does not flag multiple imports as errors, this simplicity can lead to issues. For instance, importing the same library with different parameters may result in the earlier instance being overwritten, causing unpredictable behavior. This limitation is often discussed in roadmap conversations, with hopes that future versions of Robot Framework will include more robust support for modular imports and package management. ## Clean Code Considerations Adhering to clean code principles is crucial for building maintainable, readable, and scalable projects. A modular approach offers several benefits: - **Separation of Concerns:** Grouping resources into logically separated files ensures each file has a clear, focused purpose, making the codebase easier to understand and maintain. - **Enhanced Readability:** Smaller, purpose-driven files improve readability, enabling developers to quickly locate and modify only the necessary parts of the code. - **Simplified Dependency Management:** Reducing inter-file references decreases coupling. This separation limits the impact of changes and makes your project more resilient. - **Ease of Refactoring:** When resources are organized into well-defined modules, refactoring becomes more straightforward. Developers can update or replace specific components without unintended side effects on unrelated parts. ## The Better Approach: Modularization The recommended solution is to **modularize your resources**: - **Keep the Global File Minimal:** Restrict the global resource file to only those libraries and resources that are truly needed across all test cases and keyword files. - **Import Only What’s Needed:** Instead of centralizing everything, selectively import only the necessary resources into each test case or keyword file. - **Organize Resources by Function:** Structure your project by grouping resources into files based on their function. For example, separate business-specific keywords from technical ones (such as those for database or API interactions). This modular approach not only eliminates issues like circular dependencies and performance bottlenecks but also enhances maintainability and clarity. It ensures that suite settings clearly document which components are required for each test suite. ### Example A well-organized Robot Framework project might have a structure like this: ``` project/ β”œβ”€β”€ lib/ β”‚ └── UserData.py β”œβ”€β”€ resources/ β”‚ β”œβ”€β”€ api/ β”‚ β”‚ β”œβ”€β”€ authentication.resource # API auth keywords β”‚ β”‚ β”œβ”€β”€ customers.resource # Customer API endpoints β”‚ β”‚ └── orders.resource # Order API endpoints β”‚ β”œβ”€β”€ functional/ β”‚ β”‚ β”œβ”€β”€ users.resource # User domain keywords β”‚ β”‚ β”œβ”€β”€ customers.resource # Customer domain keywords β”‚ β”œβ”€β”€ ui/ β”‚ β”‚ β”œβ”€β”€ login.resource # Login page interactions β”‚ β”‚ β”œβ”€β”€ customers.resource # Customer page interactions β”‚ β”‚ └── common_elements.resource # Shared UI elements β”‚ └── common/ β”‚ β”œβ”€β”€ test_data.resource # Test data generation β”‚ └── utilities.resource # General helper keywords └── tests/ β”œβ”€β”€ api/ β”‚ └── customer_api_tests.robot # Imports only api/customers.resource β”œβ”€β”€ business/ β”‚ └── contracts.robot # Imports only ui/login.resource └── ui_tests/ └── login_tests.robot # Imports only ui/login.resource ``` In this structure, each test file imports only the specific resources it needs, avoiding a global import file. Note: Robot Framework resolves Resource imports relative to the importing file (or via absolute paths). PYTHONPATH applies to Python libraries, not resource files. RobotCode can configure analysis and discovery paths via robot.toml. Your suite settings can look like this: ::: code-group ```robot [login.robot] *** Settings *** Resource ui/login.resource Resource ui/customers.resource Resource common/test_data.resource ``` ::: and if you have a suite for functional tests, it can look like this: ::: code-group ```robot [contracts.robot] *** Settings *** Resource functional/users.resource Resource functional/customers.resource Resource common/test_data.resource ``` ::: ### Migration Guide: From Global to Modular Structure If you have an existing project with a large global resource file, consider this incremental approach: 1. **Analyze usage patterns**: - Identify which keywords/variables are actually used in each test suite - Look for natural functional groupings (UI, API, data generation, etc.) - Measure counts (keywords, variables, and resource imports) per file to prioritize refactoring; use a threshold (for example ~200 keywords) as a guide. 2. **Create specialized resource files**: - Start with one functional area (e.g., login functionality) - Extract relevant keywords into a new `login.resource` file - Maintain the original global file temporarily 3. **Gradual transition**: - Update one test suite at a time to use the specific resource - Keep the global import during transition for backward compatibility - Run tests after each change to verify functionality 4. **Progressive cleanup**: - Once all suites using specific functionality import the correct resource file - Remove those keywords from the global file - Eventually phase out the global file completely Here's a concrete example of refactoring from a global approach to a modular one: **Before (Global.resource):** ::: code-group ```robot [/tests/login_test.robot] *** Settings *** # Anti-pattern: single global import Resource resources/Global.resource *** Test Cases *** Valid Login Login To Application valid_user valid_password Get Customer Details 123 ``` ```robot [/resources/Global.resource] *** Settings *** Library SeleniumLibrary Library RequestsLibrary Library Collections Resource common/test_data.resource Resource common/utility.resource *** Keywords *** Login To Application [Arguments] ${username} ${password} Open Browser ${URL} ${BROWSER} Input Text id=username ${username} Input Password id=password ${password} Click Button id=login-button Get Customer Details [Arguments] ${customer_id} ${response}= GET ${API_URL}/customers/${customer_id} RETURN ${response.json()} ``` ::: **After:** ::: code-group ```robot [/tests/login_test.robot] *** Settings *** # Only importing what is needed Resource ui/login.resource Resource api/customers.resource *** Test Cases *** Valid Login Login To Application valid_user valid_password Get Customer Details 123 ``` ```robot [/resources/ui/login.resource] *** Settings *** Library SeleniumLibrary Resource common/utility.resource *** Keywords *** Login To Application [Arguments] ${username} ${password} Open Browser ${URL} ${BROWSER} Input Text id=username ${username} Input Password id=password ${password} Click Button id=login-button ``` ```robot [/resources/api/customers.resource] *** Settings *** Library RequestsLibrary *** Keywords *** Get Customer Details [Arguments] ${customer_id} ${response}= GET ${API_URL}/customers/${customer_id} [Return] ${response.json()} ``` ::: ## When Restructuring Isn't Possible If restructuring your project isn't an option, you can mitigate potential issues by managing warnings from your development environment. For example, you can suppress warnings related to circular dependencies and redundant imports on a per-file basis or globally. It's important to understand that suppressing warnings doesn't fix the underlying issuesβ€”it merely acknowledges them. When you choose to ignore specific diagnostics, you're making a conscious decision that these particular issues are acceptable in your codebase. This explicit acknowledgment is different from simply ignoring random warnings in your IDE. By documenting suppressions in your code or configuration files, you're communicating to your team that you understand the potential problem but have determined that it's an acceptable compromise given your project's constraints. This approach is particularly useful during transitional periods or when working with legacy codebases where perfect architectural solutions aren't immediately feasible. However, these suppressions should ideally be revisited periodically to determine if the underlying issues can eventually be resolved through refactoring. ### Suppress Warnings in Specific Files Use directives to disable warnings for circular dependencies and already-imported resources on a per-file basis. ```robot # example for disabling of specific messages for the whole file # robotcode: ignore[ResourceAlreadyImported, PossibleCircularImport] *** Settings *** Variables variables # example for disabling of specific messages for a statement Resource already_imported.resource # robotcode: ignore[ResourceAlreadyImported] Resource circular_import.resource # robotcode: ignore[PossibleCircularImport] ``` ### Suppress Warnings Globally The preferred approach to suppress warnings globally is using a `robot.toml` configuration file. This method is IDE-independent and can be checked into version control to share with your team. Create a [`robot.toml`](/03_reference/config) file in your project root with these contents: ```toml [tool.robotcode-analyze.modifiers] ignore = [ "PossibleCircularImport", "CircularImport", "ResourceAlreadyImported", "VariablesAlreadyImported", "LibraryAlreadyImported" ] ``` Alternatively, if you're working exclusively in VS Code, you can add the following to your `settings.json`, though this approach is not recommended for team environments as it only affects your local setup: ```json "robotcode.analysis.diagnosticModifiers.ignore": [ "PossibleCircularImport", "CircularImport", "ResourceAlreadyImported", "VariablesAlreadyImported", "LibraryAlreadyImported" ] ``` ## Conclusion In summary, while a single global resource file might simplify the initial setup by reducing the number of imports, it ultimately creates more problems than it solves. Issues such as circular dependencies, naming collisions, performance degradation, and decreased maintainability quickly outweigh the initial convenience. A modular resource structure adheres to clean code principles and ensures that suite settings serve as clear, documented indicators of which parts of the application are under test. If a centralized file is unavoidable, selectively suppressing warnings can help manage the associated risks. --- URL: "/04_tip_and_tricks/02_why_variable_not_found" LLMS_URL: "/04_tip_and_tricks/02_why_variable_not_found.md" --- # Why is my variable shown as "not found"? Does this sound familiar? Your Robot Framework tests are carefully written and run smoothly - but RobotCode persistently displays `VariableNotFound` errors, even though you're certain that all variables are defined and no errors are reported during runtime. In this guide, you'll learn what causes this problem, how the different handling of variables between RobotCode and Robot Framework leads to misunderstandings, and which best practices make your tests more reliable, maintainable, and transparent. ## Understanding Robot Framework Variables Variables are a fundamental building block of any test automation with Robot Framework. They allow storing and reusing values, make tests more dynamic, and improve the maintainability of your code. However, to use variables effectively, understanding their scopes is crucial. In Robot Framework, a variable's scope determines where it's available and how long it exists. Misunderstanding these scopes often leads to confusion, especially when RobotCode marks variables as "not found" even though they work at runtime. ### Variable Scopes Robot Framework distinguishes four main scopes for variables, which are hierarchically arranged ([see also Robot Framework Documentation on Variable Scopes](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#variable-scopes)): - **Local**: The narrowest scope level. Local variables exist only within the keyword in which they were created, or within a test case if defined there. They disappear as soon as the keyword or test is completed. - **Test/Task**: These variables are valid for the duration of a single test and are accessible in all keywords called by that test. Test scope variables persist across keyword calls within the same test, unlike local variables which are limited to their defining scope. - **Suite**: Suite variables are available within an entire test suite - that is, in all tests of a `.robot` file as well as in all keywords called in these tests. - **Global**: The widest scope level. Global variables are available in all test suites, tests, and keywords that run during a test execution. This hierarchical structure is important to understand as it determines how Robot Framework searches for variables and how variable overrides work. ### The `*** Variables ***` Section The `*** Variables ***` section is a fundamental component of Robot files for defining variables: - **Suite Scope:** All variables defined here automatically receive suite scope and are available throughout the file. - **Import order decides:** For variables with identical names: - The first found definition takes precedence - This applies to both definitions in the current suite and in imported resource files - For nested resource imports (when Resource A imports Resource B), the same rule applies: The first read definition wins - **Strategic overriding:** This property can be deliberately used, for example: - To control test behavior in different environments - To specifically adjust library settings This powerful technique should be used with caution. - **Command line variables have the highest priority:** Variables defined via command line parameters (`--variable` or `-v`) always override all definitions in `*** Variables ***` sections. **Example: Overriding browser settings** In this test suite, we define default browser settings that can be overridden by command line parameters: ```robot *** Settings *** Library Browser *** Variables *** ${BROWSER} chromium ${HEADLESS} FALSE *** Test Cases *** Open Browser Test New Browser browser=${BROWSER} headless=${HEADLESS} New Page https://example.com # Further test steps... Close Browser ``` **Execution with default values:** ```bash robot tests/web_tests.robot ``` Uses Chromium in normal (non-headless) mode. **Execution with Firefox in headless mode:** ```bash robot --variable BROWSER:firefox --variable HEADLESS:True tests/web_tests.robot ``` This pattern is particularly useful for: - CI/CD pipelines with different browser requirements - Parallel testing on various browsers - Local debugging (GUI mode) vs. server execution (headless) **Tip:** RobotCode provides special hints when a variable definition might override another definition or be overridden by a global variable. ### Variable Resolution When resolving variables, Robot Framework follows a strictly hierarchical search strategy: 1. **Local scope** (within the current keyword or test) 2. **Test scope** (within the current test case) 3. **Suite scope** (within the current test suite) 4. **Global scope** (valid for the entire test run) The search stops as soon as a matching variable is found - even if there are further variables with the same name in outer scopes. A local variable named `${status}` always takes precedence over variables with the same name in wider scopes. ### Setting Variables Robot Framework offers several methods to define variables and assign them a scope: - **Set keywords**: The classic method with `Set Global Variable`, `Set Suite Variable`, `Set Test Variable`, and `Set Local Variable` - **VAR syntax**: More readable syntax (available from Robot Framework 7.0) with an optional scope parameter - **Return values**: Variables created by assigning a keyword return value are local by default An important concept in Robot Framework is the **scope override mechanism**: If you define a variable with a name that already exists in a narrower scope and specify a wider scope, the variable in the narrower scope is automatically deleted. This behavior ensures that the variable has the last assigned value, regardless of the scope specified. Consider the following example: ```robot *** Test Cases *** test variable scopes # 1. Create a local variable VAR ${a_var} a local value Log ${a_var} # Output: "a local value" # 2. Create a suite variable with the same name VAR ${a_var} a suite value scope=suite # The local variable is automatically deleted Log ${a_var} # Output: "a suite value" # 3. Create a global variable with the same name VAR ${a_var} a global value scope=global # The suite variable is automatically deleted Log ${a_var} # Output: "a global value" ``` To better understand this behavior, it is recommended to run the code in the debugger and observe the variables in the Variables view. Pay special attention when variables are set in called keywords with a higher scope: ```robot *** Test Cases *** test variable scopes VAR ${a_var} a local value Log ${a_var} # Output: a local value Do Something Log ${a_var} # Output: a global value - the local variable was overridden *** Keywords *** Do Something VAR ${a_var} a global value scope=global ``` Caution: By setting a variable with the same name but in a different scope in the `Do Something` keyword, the local variable in the calling test is overridden. This can lead to hard-to-understand effects if you do not explicitly account for this behavior. ## Why RobotCode Reports "Variable not found" ### Runtime vs. Static Analysis **Robot Framework** is an interpreter that processes your `.robot` files **at runtime** sequentially: - Variables are dynamically evaluated - Scopes are created and destroyed during test execution - Variable definitions through `Set Suite Variable`, `Set Global Variable`, or the `VAR` syntax with scope parameters only take effect when the corresponding code section is executed - Only at this moment do the variables become known and usable in the specified scope **RobotCode**, on the other hand, performs a **static analysis**: - Your code is analyzed before execution - Cannot predict dynamic assignments or conditional execution paths - Must work with information available at analysis time This fundamental discrepancy explains why RobotCode marks variables as `VariableNotFound` even when they would work at runtime. ### Technical Limitations The following points explain why RobotCode sometimes does not recognize variables even though they would exist at runtime. - **No call analysis:** RobotCode cannot track variable assignments across keyword calls. If a keyword sets a suite/global variable, RobotCode cannot trace this back to the calling code. **Example:** A keyword `Setup Environment` sets `${CONFIG}`, but RobotCode cannot recognize that `${CONFIG}` would be defined by calling this keyword. **Why can't RobotCode do this?** - **Technically challenging:** A complete call analysis would require simulating all possible execution paths - including conditional branches and loops. - **Dynamic language elements:** Robot Framework allows: - Conditional execution paths that are not predictable - Dynamically generated keyword calls (`Run Keyword ${dynamic_name}`) - Imports at runtime ([`Import Library ${lib_name}`](https://robotframework.org/robotframework/latest/libraries/BuiltIn.html#Import%20Library), [`Import Resource ${resource_path}`](https://robotframework.org/robotframework/latest/libraries/BuiltIn.html#Import%20Resource)) - Dynamically generated variable names ([`${Home ${name}}`](https://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#variables-inside-variables)) - **Performance:** Analyzing complex test suites with all possible execution paths would significantly slow down the IDE. - **Unlimited search space:** Nested calls across multiple files and potentially recursive structures make a complete analysis impossible. - **Unpredictable execution order:** The execution order in Robot Framework is not always statically predictable. RobotCode cannot know during analysis: - Whether tests are filtered with **tags** (`--include`/`--exclude`/`--skip`) - Whether the order is changed by **command line options** (`--randomize`) - Whether tests are skipped by **conditional execution** (`Skip If`, `Run Keyword If`) - Whether **dynamically generated tests** are used (test templates with variable data) - Whether **parallel execution** (e.g., with Pabot) is used - Whether **external listeners or prerunmodifiers** change the execution or execution order **Example:** A suite contains two tests - the first defines `${CONFIG_VALUE}` as a suite variable, the second uses it: ```robot *** Test Cases *** Setup Configuration [Tags] setup Set Suite Variable ${CONFIG_VALUE} production Use Configuration [Tags] functional Log ${CONFIG_VALUE} # Works only if the setup test was executed ``` If the test is run with `--include functional`, the variable is missing. - **Conditional assignments and loops:** If variables are only set under certain conditions (e.g., in `IF` statements or loops) or in dynamic contexts, RobotCode cannot predict the actual execution path. Examples include: - Variables defined only in an `IF` branch - Variables created only within a `FOR` loop - Variables whose assignment depends on dynamic conditions ```robot *** Test Cases *** test different environments IF '${ENV}' == 'production' Set Suite Variable ${API_URL} https://api.production.example.com ELSE Set Suite Variable ${TEST_URL} https://api.test.example.com END Log ${API_URL} # [!code error] Error: VariableNotFound Log ${TEST_URL} # [!code error] Error: VariableNotFound ``` - **Suite order and `__init__.robot`:** Robot Framework uses a hierarchical execution model with folders and files as test suites. When executing a folder as a suite, Robot Framework first processes the `__init__.robot` file of that folder, if present. This file can define suite setup/teardown keywords as well as test/task setups that then apply to all tests within the entire folder structure. This leads to an important peculiarity: Variables defined in these `__init__.robot` files or their suite setups are available at runtime in all subordinate tests. However, this only applies if you run the entire folder. When directly executing a single `.robot` file, parent `__init__.robot` files may not be considered at all - accordingly, the variables defined in them do not exist. RobotCode cannot predict during its static analysis whether a single file or an entire folder will be executed. ### Summary of technical reasons: | Problem | At runtime | During static analysis | | ---------------------- | -------------------------------------------------- | ------------------------------------------------------ | | Call analysis | Variable is defined by called keyword | No complete tracking of call chains | | Execution order | Depends on CLI options and conditional executions | Cannot predict which tests will be executed | | Conditional assignments| Only one path is actually executed | All possible paths would need to be analyzed | | Suite folder | Available depending on execution context | Cannot know the exact execution context | ### RobotCode's Conservative Strategy RobotCode deliberately follows a cautious approach to variable recognition, partly due to technical limitations regarding complexity and performance. It only marks a variable as valid if it is explicitly defined in one of the following ways: - As a command line parameter - In a `*** Variables ***` section - In the currently analyzable scope (such as keyword arguments or local variables) All other variables are consistently marked as `VariableNotFound` - even if they might exist at runtime. This conservative strategy is not merely a technical limitation but a deliberate design principle that offers significant advantages for test quality and maintenance: - **Error prevention:** The variable might actually be undefined, which would only lead to errors at runtime. Such runtime errors are particularly tricky as they may only occur under certain conditions and take a lot of time to debug. Tests could fail on CI/CD systems or in specific environments even though they work fine locally. RobotCode helps you identify and fix these potential issues early during development - long before they lead to hard-to-trace errors in production-like environments. - **Code clarity:** Developers cannot immediately tell if a variable is correctly defined when its definition is hidden in other files or nested keywords. A particular risk arises when variables with identical names are set via `Set Global Variable` in different resource files. It can easily happen that a team member uses an already used variable name (`${CONFIG}`) for a completely different purpose - while you store server settings with it, someone else uses the same name for test data. Without explicit definitions, undetected conflicts and hard-to-trace errors arise. - **Maintainability:** Implicit variable definitions scattered across multiple resource files or occurring only under certain execution conditions create unwanted dependencies and complicate long-term maintenance. When variables "magically" appear - defined somewhere deep in keywords or rarely executed code paths - every change becomes a risk. Teams spend unnecessary time figuring out where a variable was originally set and whether changing it might have unintended side effects. As test suites grow, this problem intensifies exponentially: What was obvious to the original developer becomes an opaque web of hidden dependencies for the team. RobotCode's conservative warnings enforce cleaner design with explicit dependencies. - **Documentation:** Explicit variable definitions serve as integrated documentation of your code. They make it immediately clear which variables are used, what type they have, and what default values are intended. This significantly eases onboarding for new team members as they don't have to search the entire code to understand where a variable comes from or what purpose it serves. Especially in larger test projects, this kind of self-documentation becomes an important factor for the long-term maintainability and extensibility of the test suite. The `VariableNotFound` messages should therefore not be seen as annoying warnings but as valuable development tools. They encourage critical reflection on your code and promote better design decisions: "Is a suite variable really necessary here, or is there a more elegant solution?" These diagnostic messages foster an architectural understanding of the test structure, improve code quality, and ultimately support the development of explicit, self-explanatory structures. This principle applies to all diagnostic messages in RobotCode - they are not mere error indications but valuable guardrails on the path to high-quality, robust test suites. ## Solutions and Best Practices ### Explicit Variable Definitions The most reliable way to avoid `VariableNotFound` errors is to explicitly define variables in the `*** Variables ***` section, especially when you plan to use `Set Suite Variable`, `Set Global Variable`, or the `VAR` statement with suite/global scope later in your tests. **Key principle**: Always provide default values in `*** Variables ***` for variables that will be dynamically set with wider scopes during test execution. This ensures that RobotCode can statically recognize these variables, even before they are assigned their runtime values. **Example: Variables that will be set dynamically** ```robot *** Variables *** # Define defaults for variables that will be set dynamically ${AUTH_TOKEN} ${EMPTY} # Will be set by login keyword ${CURRENT_USER_ID} ${NONE} # Will be set during user creation ${TEST_DATA_PATH} ${EMPTY} # Will be set based on environment *** Keywords *** Login User [Arguments] ${username} ${password} ${token}= Get Auth Token ${username} ${password} # RobotCode recognizes ${AUTH_TOKEN} because it's pre-defined Set Suite Variable ${AUTH_TOKEN} ${token} Create Test User ${user_id}= Generate User ID # RobotCode recognizes ${CURRENT_USER_ID} because it's pre-defined VAR ${CURRENT_USER_ID} ${user_id} scope=SUITE *** Test Cases *** User Management Test Login User testuser password123 Create Test User Log Using token: ${AUTH_TOKEN} # βœ… No VariableNotFound Log Created user: ${CURRENT_USER_ID} # βœ… No VariableNotFound ``` **Best Practice: Use descriptive variable names with clear prefixes** ```robot *** Variables *** # Configuration variables - use CONFIG_ prefix ${CONFIG_BASE_URL} https://api.example.com ${CONFIG_TIMEOUT} 30 seconds ${CONFIG_RETRY_COUNT} 3 # Test data variables - use DATA_ prefix ${DATA_USER_EMAIL} test@example.com ${DATA_USER_PASSWORD} SecurePassword123 # Environment-specific variables with defaults ${ENV} test # Can be overridden via command line ${BROWSER} chrome # Default browser for web tests ``` **Pattern: Variable files for complex configurations** For more complex scenarios, use Python variable files that RobotCode can analyze: ```python # variables/config.py import os # These variables will be recognized by RobotCode BASE_URL = os.getenv('BASE_URL', 'https://api.test.example.com') API_KEY = os.getenv('API_KEY', 'test-api-key') # Dictionary variables for structured data DATABASE_CONFIG = { 'host': os.getenv('DB_HOST', 'localhost'), 'port': int(os.getenv('DB_PORT', '5432')), 'name': os.getenv('DB_NAME', 'testdb') } ``` Usage in your robot file: ```robot *** Settings *** Variables variables/config.py *** Test Cases *** API Test Log Using API at ${BASE_URL} Log Database host: ${DATABASE_CONFIG}[host] ``` **Pattern: Resource files with shared variables** Create resource files that define commonly used variables: ```robot # resources/common_variables.resource *** Variables *** ${WAIT_TIMEOUT} 10 seconds ${SCREENSHOT_DIR} ${OUTPUT_DIR}/screenshots ${LOG_LEVEL} INFO # Complex data structures &{DEFAULT_HEADERS} Content-Type=application/json Accept=application/json @{SUPPORTED_BROWSERS} chrome firefox edge ``` Then import in your test files: ```robot *** Settings *** Resource resources/common_variables.resource *** Test Cases *** Use Shared Variables Log Timeout is ${WAIT_TIMEOUT} Log Supported browsers: @{SUPPORTED_BROWSERS} ``` This approach provides several benefits: - RobotCode recognizes all variables immediately - Variables are documented and centralized - Easy to maintain and update - Clear separation of concerns ### Default Value Handling When working with variables that might not always be defined, it's crucial to implement proper default value handling. RobotCode can better understand your code when you explicitly handle potentially undefined variables. **Pattern: Using Variable Should Exist with fallback** ```robot *** Keywords *** Get Configuration Value [Arguments] ${key} ${default}=${EMPTY} ${exists}= Run Keyword And Return Status ... Variable Should Exist ${${key}} IF ${exists} ${value}= Set Variable ${${key}} ELSE ${value}= Set Variable ${default} Log Variable ${key} not found, using default: ${default} WARN END RETURN ${value} ``` **Pattern: Safe variable access with Get Variable Value** Robot Framework 5.0+ provides `Get Variable Value` for safe variable access: ```robot *** Test Cases *** Safe Variable Access # Get variable with default if not exists ${url}= Get Variable Value ${API_URL} https://default.example.com # Check nested variables safely ${timeout}= Get Variable Value ${CONFIG.timeout} 30 # Use None as default to check existence ${optional_var}= Get Variable Value ${OPTIONAL_SETTING} ${None} IF $optional_var is not None Log Optional setting is: ${optional_var} END ``` **Pattern: Defensive programming with variable validation** Create a keyword that validates required variables at the start of your test suite: ```robot *** Keywords *** Validate Required Variables [Documentation] Ensures all required variables are defined @{required_vars}= Create List ... BASE_URL ... API_KEY ... TEST_USER FOR ${var} IN @{required_vars} TRY Variable Should Exist ${${var}} Log βœ“ Variable ${var} is defined EXCEPT Fail Required variable ${var} is not defined! END END *** Test Cases *** Setup Test Environment [Setup] Validate Required Variables Log All required variables are present ``` **RobotCode Quick Fix Integration** When RobotCode shows a `VariableNotFound` error, you can use the built-in quick fixes: 1. **Create suite variable** - Adds the variable to `*** Variables ***` section 2. **Create local variable** - Creates a local variable with `Set Variable` 3. **Add as keyword argument** - Adds the variable as a keyword parameter These quick fixes help maintain clean, analyzable code while resolving variable issues. ### Using RETURN Statements (RF 5.0+) The `RETURN` statement (Robot Framework 5.0+) provide the cleanest way to pass data between keywords without relying on suite or global variables. This approach makes your code more maintainable and helps RobotCode understand the data flow. In older Robot Framework versions there was a `[Return]` setting that allowed declaring a fixed return value for a keyword; it did not support conditional returns and was deprecated in Robot Framework 7.0. Use the more flexible `RETURN` statement (introduced in RF 5.0), which supports conditional returns and can be used inside IF/FOR constructs. **RETURN statement** ```robot *** Keywords *** Calculate Total Price [Arguments] ${base_price} ${tax_rate}=0.1 ${discount}=0 ${tax_amount}= Evaluate ${base_price} * ${tax_rate} ${discounted_price}= Evaluate ${base_price} - ${discount} ${total}= Evaluate ${discounted_price} + ${tax_amount} RETURN ${total} Get User Details [Arguments] ${user_id} ${name}= Query Database SELECT name FROM users WHERE id=${user_id} ${email}= Query Database SELECT email FROM users WHERE id=${user_id} ${role}= Query Database SELECT role FROM users WHERE id=${user_id} RETURN ${name} ${email} ${role} *** Test Cases *** Test With Return Values ${price}= Calculate Total Price 100 0.2 10 Should Be Equal As Numbers ${price} 108 ${name} ${email} ${role}= Get User Details 123 Log User: ${name} (${email}) has role: ${role} ``` **Pattern: Data transformation pipelines** Chain keywords using return values instead of setting suite variables: ```robot *** Keywords *** Fetch Raw Data [Arguments] ${source} ${data}= Get File ${source} RETURN ${data} Parse JSON Data [Arguments] ${raw_data} ${parsed}= Evaluate json.loads('''${raw_data}''') RETURN ${parsed} Transform Data [Arguments] ${data} ${transformed}= Create Dictionary FOR ${key} ${value} IN &{data} ${new_value}= Convert To Upper Case ${value} Set To Dictionary ${transformed} ${key}=${new_value} END RETURN ${transformed} *** Test Cases *** Data Pipeline Test ${raw}= Fetch Raw Data data.json ${parsed}= Parse JSON Data ${raw} ${result}= Transform Data ${parsed} Log Transformed data: ${result} ``` **Pattern: Configuration builders** Build complex configurations without polluting the variable scope: ```robot *** Keywords *** Create Test Configuration [Arguments] ${environment}=test ${config}= Create Dictionary IF "${environment}" == "production" Set To Dictionary ${config} ... url=https://api.production.example.com ... timeout=60 ... retry=5 ELSE IF "${environment}" == "staging" Set To Dictionary ${config} ... url=https://api.staging.example.com ... timeout=30 ... retry=3 ELSE Set To Dictionary ${config} ... url=https://api.test.example.com ... timeout=10 ... retry=1 END RETURN ${config} Initialize API Client [Arguments] ${config} ${client}= Create API Client ... base_url=${config}[url] ... timeout=${config}[timeout] RETURN ${client} *** Test Cases *** API Test With Configuration ${config}= Create Test Configuration staging ${client}= Initialize API Client ${config} ${response}= Call API ${client} /health Should Be Equal ${response.status} 200 ``` **Pattern: Error handling with optional returns** Handle errors gracefully while maintaining clear data flow: ```robot *** Keywords *** Safe Database Query [Arguments] ${query} TRY ${result}= Execute SQL Query ${query} ${status}= Set Variable SUCCESS EXCEPT AS ${error} ${result}= Set Variable ${None} ${status}= Set Variable ERROR: ${error} Log Query failed: ${error} WARN END RETURN ${result} ${status} *** Test Cases *** Database Test With Error Handling ${data} ${status}= Safe Database Query SELECT * FROM users IF "${status}" == "SUCCESS" Log Retrieved ${data.rowcount} users ELSE Log Query failed: ${status} ERROR END ``` **Benefits for RobotCode analysis:** - Clear data flow that RobotCode can trace - No hidden variable dependencies - Explicit input/output contracts - Better IntelliSense and autocomplete support - Easier refactoring and testing **Migration tip:** When refactoring old tests that use `Set Suite Variable`, replace them with keywords that RETURN values: ```robot # Old approach - RobotCode can't trace this *** Keywords *** Setup Test Data ${user}= Create Test User Set Suite Variable ${TEST_USER} ${user} ${token}= Get Auth Token ${user} Set Suite Variable ${AUTH_TOKEN} ${token} # New approach - Clear data flow *** Keywords *** Setup Test Data ${user}= Create Test User ${token}= Get Auth Token ${user} RETURN ${user} ${token} *** Test Cases *** Test With Clear Data Flow ${user} ${token}= Setup Test Data # Variables are explicit and traceable ``` ### Quick Reference Guide #### Checklist βœ… **DO:** - Define shared variables in `*** Variables ***` sections - Use RETURN statements for passing data between keywords - Leverage variable files for complex configurations - Use descriptive variable names with consistent prefixes - Validate required variables at test setup - Use `Get Variable Value` for optional variables - Apply RobotCode's quick fixes when appropriate ❌ **DON'T:** - Rely on `Set Suite/Global Variable` for data passing - Create variables in deeply nested keywords - Use dynamic variable names unnecessarily - Ignore RobotCode's VariableNotFound warnings - Mix variable definition patterns within the same suite #### RobotCode Features 1. **Quick Fixes (Ctrl+.):** - Create suite variable - Create local variable - Add as keyword argument - Disable warning for line 2. **IntelliSense Support:** - Autocomplete for defined variables - Hover documentation for variables - Go to definition (F12) 3. **Refactoring Support:** - Rename variable (F2) - Extract variable - Inline variable #### Common Patterns Reference | Scenario | Recommended Approach | Avoid | |----------|---------------------|-------| | Configuration values | `*** Variables ***` section or variable files | Set Suite Variable in setup | | Test data | Keyword arguments and RETURN | Global variables | | Temporary values | Local variables with VAR | Suite-level variables | | Cross-file sharing | Resource files with variables | Dynamic imports | | Environment-specific | Command-line variables | Hardcoded conditionals | ## Conclusion Understanding how RobotCode analyzes variables and following the best practices outlined in this guide will help you write more maintainable and reliable Robot Framework tests. While the `VariableNotFound` warnings might seem frustrating at first, they are valuable indicators that guide you toward better code structure and clearer variable management. Remember that RobotCode's conservative approach to variable recognition is designed to help you catch potential issues early in development rather than during test execution. By embracing explicit variable definitions and clear data flow patterns, you'll create test suites that are not only free from variable warnings but also easier to understand, maintain, and scale. The key takeaway: Make your variables visible to both RobotCode and your team members through explicit definitions and clear scoping. Your future self and your colleagues will thank you for it. --- URL: "/04_tip_and_tricks/03_vscode_customizations" LLMS_URL: "/04_tip_and_tricks/03_vscode_customizations.md" --- # Customizing Visual Studio Code for using RobotCode This guide helps you customize VSCode to improve your experience when working with RobotCode. ## Editor Style You can change how Robot Framework files appear in the VSCode editor, independently of your current theme. These customizations can make your code more readable by highlighting different elements. See the difference: | Before | After | | ----------------------------------------------------------------- | ----------------------------------------------------------- | | ![Without customization](./images/without_customization.gif) | ![With customization](./images/with_customization.gif) | ### How to Apply Customizations 1. Open your VSCode user settings: - Press Ctrl + Shift + P (Windows/Linux) or CMD + Shift + P (Mac) - Type: `Preferences: Open Settings (JSON)` 2. Add the following code to your `settings.json` file: ```jsonc "editor.tokenColorCustomizations": { "textMateRules": [ { "scope": "variable.function.keyword-call.inner.robotframework", "settings": { "fontStyle": "italic" } }, { "scope": "variable.function.keyword-call.robotframework", "settings": { //"fontStyle": "bold" } }, { "scope": "string.unquoted.embeddedArgument.robotframework", "settings": { "fontStyle": "italic" } }, { "scope": "entity.name.function.testcase.name.robotframework", "settings": { "fontStyle": "bold underline" } }, { "scope": "entity.name.function.keyword.name.robotframework", "settings": { "fontStyle": "bold italic" } }, { "scope": "variable.name.readwrite.robotframework", "settings": { //"fontStyle": "italic", } }, { "scope": "keyword.control.import.robotframework", "settings": { "fontStyle": "italic" } }, { "scope": "keyword.other.header.setting.robotframework", "settings": { "fontStyle": "bold underline" } }, { "scope": "keyword.other.header.variable.robotframework", "settings": { "fontStyle": "bold underline" } }, { "scope": "keyword.other.header.testcase.robotframework", "settings": { "fontStyle": "bold underline" } }, { "scope": "keyword.other.header.keyword.robotframework", "settings": { "fontStyle": "bold underline" } }, { "scope": "keyword.other.header.setting.robotframework", "settings": { "fontStyle": "bold underline" } }, { "scope": "keyword.other.header.comment.robotframework", "settings": { "fontStyle": "bold italic underline" } }, { "scope": "string.unquoted.escape.robotframework", "settings": { //"foreground": "#FF0000", } } ] }, "editor.semanticTokenColorCustomizations": { "rules": { "*.documentation:robotframework": { "fontStyle": "italic", //"foreground": "#aaaaaa" } } } ``` --- URL: "/04_tip_and_tricks/04_neovim_lsp_setup" LLMS_URL: "/04_tip_and_tricks/04_neovim_lsp_setup.md" --- # Configuring RobotCode as Language Server for Neovim [Neovim](https://neovim.io/) is an extensible Vim-based text editor. While there is no fully featured plugin of RobotCode that you can just install and use "as is" like for VS Code, it is still possible to leverage the [Language Server](https://microsoft.github.io/language-server-protocol/) provided by RobotCode to enable static analysis, go-to-definition, and other useful features. This guide shows two alternatives to set up and configure your Neovim installation to use the RobotCode language server properly. ## Common Prerequisites To follow this guide, the reader is expected to already know the basics of * installing and configuring Neovim * adding plugins to Neovim * Python virtual environments and how to create them Regardless of the option you choose, using a language server in Neovim always requires to * **install** the language server * **configure** the language server * **enable** the language server This guide assumes a Neovim version >= 0.11 and uses the built-in LSP API. ## The Common Pitfall When Using Mason and nvim-lspconfig Two plugins are commonly used to install and configure LSP servers for Neovim, and are included in Neovim starter distributions like [LazyVim](https://www.lazyvim.org/): * [mason.nvim](https://github.com/mason-org/mason.nvim): a package manager that lets you install and manage LSP servers, including RobotCode * [nvim-lspconfig](https://github.com/neovim/nvim-lspconfig): quickstart configurations for LSP servers, including a configuration for RobotCode While this combination sounds ideal, you will quickly experience import errors for third party libraries and custom keywords. Understanding why this happens is important to understand the differences of the alternatives discussed below. ![Import Errors in Neovim](./images/neovim-mason-import-errors.png) `Mason` installs every package in a dedicated virtual environment, and makes the corresponding binary available globally from within Neovim. `nvim-lspconfig` provides the following configuration: ```lua return { cmd = { 'robotcode', 'language-server' }, -- [!code focus] filetypes = { 'robot', 'resource' }, root_markers = { 'robot.toml', 'pyproject.toml', 'Pipfile', '.git' }, get_language_id = function(_, _) return 'robotframework' end, } ``` This will start the language server by using the first `robotcode` binary found in `PATH`, which most likely is the one installed via `Mason`. In this situation, RobotCode can only "see" the packages that are available in the virtual environment created by `Mason`, lacking all third party keyword libraries you may have installed in your project's virtual environment. ## Setup Alternatives If you want a simple LSP configuration and have RobotCode installed in your project anyway (or don't mind adding it), [Option 1](#option-1-use-local-installation-of-robotcode) is ideal. If you prefer to install RobotCode globally via `Mason`, you need to tweak the LSP configuration a bit - see [Option 2](#option-2-use-globally-installed-robotcode-and-set-pythonpath). ### Option 1: Use Local Installation of RobotCode The easiest way to run RobotCode in the context of your project's virtual environment is to add `robotcode[languageserver]` (or simply `robotcode[all]`) to your dependencies. To configure the RobotCode language server, install `nvim-lspconfig`, or create the file manually under `~/.config/nvim/lsp/robotcode.lua`: ```lua ---@brief --- --- https://robotcode.io --- --- RobotCode - Language Server Protocol implementation for Robot Framework. return { cmd = { 'robotcode', 'language-server' }, filetypes = { 'robot', 'resource' }, root_markers = { 'robot.toml', 'pyproject.toml', 'Pipfile', '.git' }, get_language_id = function(_, _) return 'robotframework' end, } ``` Enable the LSP server by adding the following line to `~/.config/nvim/init.lua`: ```lua vim.lsp.enable("robotcode") ``` Before starting Neovim, make sure to first activate the virtual environment. If your virtual environment is created in the folder `.venv`: ::: code-group ``` shell [Mac/Linux] source .venv/bin/activate nvim ``` ``` ps [Windows PowerShell/pwsh] .venv\Scripts\activate.ps1 nvim ``` ``` cmd [Windows CMD] .venv\Scripts\activate.cmd nvim ``` ::: This ensures the `robotcode` binary from your project's environment is the first in `PATH`. ### Option 2: Use Globally Installed RobotCode and Set PYTHONPATH With this approach it is not necessary to install RobotCode in each and every project. You use `Mason` to install and update RobotCode globally for Neovim. The LSP configuration provides a helper function to set the PYTHONPATH variable so the globally installed RobotCode can import all your project specific libraries. First, install RobotCode by executing `:MasonInstall robotcode` from within Neovim, or by using the `Mason` UI (`:Mason`). Next, create the LSP configuration under `~/.config/nvim/lsp/robotcode.lua`: ```lua ---@brief --- --- https://robotcode.io --- --- RobotCode - Language Server Protocol implementation for Robot Framework. ---@return string|nil local function get_python_path() -- Search for the site-packages directory in the .venv folder. -- The folder structure differs between Windows and Unix, -- but this function handles both. local cwd = vim.uv.cwd() local project_site_packages = vim.fs.find("site-packages", { path = cwd .. "/.venv", type = "directory", limit = 1, })[1] if not project_site_packages then -- If the site-packages were not found, RobotCode will still work, -- but import errors will appear for third party libraries. vim.notify("RobotCode: project virtual environment not found.") return nil end local pythonpath = project_site_packages if vim.env.PYTHONPATH then -- Preserve original PYTHONPATH if already set by some other plugin pythonpath = project_site_packages .. ":" .. vim.env.PYTHONPATH end return pythonpath end local python_path = get_python_path() ---@type vim.lsp.Config return { cmd = { "robotcode", "language-server" }, cmd_env = python_path and { PYTHONPATH = python_path } or nil, filetypes = { "robot", "resource" }, root_markers = { "robot.toml", "pyproject.toml", "Pipfile", ".git" }, get_language_id = function(_, _) return "robotframework" end, } ``` Note that `get_python_path` assumes that your virtual environment is created inside your project folder in a folder called `.venv`, which is a widespread standard but not necessarily true for some tools (e.g. `pyenv`). Finally, enable the LSP server in `~/.config/nvim/init.lua`: ```lua vim.lsp.enable("robotcode") ``` This solution also works if you have some projects that have RobotCode installed locally. The downside is that you may have to tweak `get_python_path` if you don't follow the `.venv` folder convention. ## Final Notes Be aware that this setup only enables the features provided by the language server, i.e. diagnostics, completions, go-to-definition etc. Unlike the VS Code plugin this setup does not enable you to run or debug robot tests from within Neovim. --- URL: "/05_contributing" LLMS_URL: "/05_contributing.md" --- # Support & Contribute RobotCode is a powerful, open-source toolset designed to enhance development with Robot Framework. With features like intelligent code completion, test discovery, and seamless debugging, RobotCode makes test automation **faster, easier, and more efficient** for teams and individuals worldwide. ## Built for the Community, by the Community RobotCode is **100% open-source and community-driven**. Our mission is to provide a **modern, intuitive, and feature-rich development experience** for Robot Framework users. Unlike commercial alternatives, RobotCode is developed **by and for the community**, allowing it to adapt quickly to user needs and ensuring a transparent, collaborative development process. Maintaining a project of this scale requires **continuous development, support, and infrastructure**. This includes keeping up with frequent Robot Framework updates, ensuring compatibility with multiple IDEs, and optimizing performance for larger test suites. As RobotCode grows, so does the demand for **new features, bug fixes, documentation, and long-term stability**. That’s why we need **your support** to keep RobotCode sustainable and thriving. ## Why Support RobotCode? Your contributions help us: - **Continue active development** – More funding means more dedicated time for improvements and new features. - **Fix bugs faster** – With financial support, we can prioritize critical issues and reduce delays in updates. - **Ensure long-term stability** – Keeping up with the latest Robot Framework versions and evolving industry needs. - **Enhance documentation & learning resources** – Making it easier for individuals and teams to get started with RobotCode. - **Expand community support** – More engagement, better responsiveness, and stronger collaboration. **Transparent Funding:** Every contribution is publicly tracked, ensuring complete transparency on how funds are used. ## How You Can Support RobotCode ### Financial Contributions The most direct way to help RobotCode stay sustainable and grow is through financial contributions. If you or your company use RobotCode and find it valuable, consider supporting the project: - **[Become a Backer or Sponsor on Open Collective](https://opencollective.com/robotcode)** – Recurring or one-time donations to support ongoing development. - **[Sponsor RobotCode on GitHub](https://github.com/sponsors/robotcodedev)** – Show your support directly through GitHub Sponsors. ### Contribute Beyond Financial Support RobotCode thrives on community contributions. Active participation helps shape the future of the project. Whether you're a developer, writer, tester, or advocate, your contributions make a difference. We understand that not everyone can contribute financially, but **there are many other valuable ways to support RobotCode**: - **Contribute Code** – Help improve RobotCode by fixing bugs, adding features, or optimizing performance on [GitHub](https://github.com/robotcode-dev/robotcode). - **Improve Documentation** – Writing tutorials, FAQs, or guides makes it easier for new users to start using RobotCode. - **Report Bugs & Share Feedback** – Testing new releases, reporting issues, and suggesting improvements helps the project evolve. - **Spread the Word** – Recommend RobotCode to colleagues, write blog posts, give talks, or share it on social media. - **Engage with the Community** – Join discussions, answer questions, and help others in forums or social media channels. **Every form of support matters!** Whether through financial contributions or active participation, your help ensures RobotCode remains a thriving, open-source project for the entire community. You are an essential part of this project, and every contribution makes a difference. ## Join Us in Shaping the Future of Test Automation By supporting RobotCode, you help ensure that **Robot Framework users worldwide have access to a powerful, reliable, and evolving toolset**. Together, we can make **test automation better for everyone**. **[Support RobotCode on Open Collective](https://opencollective.com/robotcode)** **[Sponsor RobotCode on GitHub](https://github.com/sponsors/robotcodedev)** --- URL: "/news" LLMS_URL: "/news.md" title: "News" --- # News Release announcements and news about RobotCode.

{{ post.frontmatter.title }}

{{ new Date(post.frontmatter.date).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }) }}

--- URL: "/news/2026-03-31-whats-new-v2.5.0" LLMS_URL: "/news/2026-03-31-whats-new-v2.5.0.md" title: "What's New in v2.5.0" date: --- # What's New in RobotCode v2.5.0 If you've ever opened a large Robot Framework project and gone for coffee while **RobotCode** was still thinking β€” this release is for you. Version 2.5.0 is all about **speed**: faster startup, faster analysis, faster code completion. And a few new tricks on top. ## Instant Startup with Analysis Caching The biggest change you'll notice: **RobotCode remembers**. When you open a project for the second time, all the analysis work from your last session is still there β€” diagnostics, code completion, navigation, everything loads almost instantly. Behind the scenes, **RobotCode** now stores fully resolved analysis data in a local SQLite database. Instead of re-analyzing every file on every IDE start, it loads cached results and only re-processes files that actually changed. For projects with hundreds of Robot files, this can cut startup from minutes down to seconds. This is **enabled by default** β€” there's nothing to configure. The cache is automatically invalidated when your source files change, when library dependencies are updated, when environment variables or command-line variables differ, or when you update **RobotCode** itself. If something changes, the affected parts are re-analyzed β€” everything else comes straight from cache. Since this is a new feature, you can disable it if you run into any issues: ```toml # robot.toml [tool.robotcode-analyze.cache] cache-namespaces = false ``` or via the CLI: ```bash robotcode analyze --no-cache-namespaces ``` Multiple processes (the language server, CLI commands, parallel analyze runs) can safely access the cache at the same time thanks to file-level locking. No corruption, no conflicts. ## Performance: The Numbers Even without the cache, this release is noticeably faster. Here's what changed: - **No more 30-minute hangs on large projects.** Robot Framework's `variable_not_found` runs a fuzzy "Did you mean…?" search on every unresolved variable β€” a nice idea, but O(nΓ—m) over all variable candidates. For big projects (375+ files), this could freeze the analysis for over 30 minutes. **RobotCode** now skips that search entirely since it never uses the suggestion text. Problem solved. ([#587](https://github.com/robotcodedev/robotcode/issues/587)) - **Keyword matching is 94% faster.** The `KeywordMatcher` used to be instantiated from scratch on every lookup β€” about 7.5 million times per analysis run. It's now cached on the `KeywordDoc` itself. Combined with a new dict-based index in `KeywordStore`, keyword lookups went from linear scan to O(1) for non-embedded keywords. Overall analysis time dropped by **22%** with **31% fewer function calls**. - **File resolution is 28% faster.** Swapping `pathlib.Path` for `os.path` string operations in the hot path of file resolution plus lazy-caching of valid `sys.path` entries cut warm-start wall time by nearly a third. - **Less memory per document.** Each document used to keep two cached AST models. Now there's just one, saving around 200–500 KB per file. That adds up quickly in a big workspace. - **Faster cache loading.** Cached namespace data now includes source hints that let **RobotCode** skip expensive filesystem lookups (`find_resource`) when the cached paths still exist on disk. Cache entries use lazy deserialization β€” data blobs are only unpickled on actual cache hits, not on every lookup. - **`ArgumentSpec.resolve()` actually caches now.** A subtle bug caused `RobotArgumentSpec` to be recreated on every call (100K times per run) instead of being cached. Fixed β€” instantiation calls dropped by **98.7%**. ## Smarter Code Completion for Type Hints If you write Python libraries with type hints like `Literal["fast", "slow", "auto"]`, **RobotCode** now picks up on those and shows the allowed values directly in the completion list. This works for `Union` types containing `Literal` too, so `Literal["x", "y"] | int` will offer `x` and `y` as suggestions. No more switching to the library docs just to look up which string values a keyword accepts β€” the editor tells you right there. ## Find Unused Keywords & Variables from the CLI Unused keywords and variables are the kind of thing that quietly accumulates in any project. **RobotCode** can now detect them when running `robotcode analyze code` from the command line β€” great for CI pipelines or periodic cleanup sessions. Enable it in your `robot.toml`: ```toml [tool.robotcode-analyze.code] collect-unused = true ``` Or toggle it per invocation: ```bash robotcode analyze code --collect-unused robotcode analyze code --no-collect-unused ``` ## Full Control over the Analysis Cache A new `robotcode analyze cache` command group gives you visibility into what's cached and lets you manage it when needed: ```bash robotcode analyze cache path # where is the cache stored? robotcode analyze cache info # cache statistics, per-section breakdown robotcode analyze cache list # list cached entries (supports glob filtering with -p) robotcode analyze cache clear # remove cached entries by section robotcode analyze cache prune # wipe the entire cache ``` All output respects `--format` (text/json/toml) and `--no-color`, so it plays nicely with scripts and CI. You can also point the cache to a custom directory via the `ROBOTCODE_CACHE_DIR` environment variable. The VS Code extension automatically sets this in the integrated terminal, so your CLI commands and the language server always share the same cache without any manual setup. ## Bug Fixes - Fixed cache validation for libraries imported via relative paths β€” no longer triggers unnecessary full rebuilds on warm start. - Variable names with trailing `=` are now stripped correctly by the resource builder ([#546](https://github.com/robotcodedev/robotcode/issues/546)). - **RobotCode** no longer overrides the `source` field on AST blocks when Robot Framework itself already sets it ([#588](https://github.com/robotcodedev/robotcode/issues/588)). - Fixed a race condition when accessing workspace language settings in multi-workspace setups. ## Under the Hood A lot of internal work went into this release to prepare for future features: - **Workspace-wide reference index (ProjectIndex)** β€” **RobotCode** now maintains an incrementally updated inverse index across your entire workspace. When a file changes, only its references are updated instead of scanning everything. This covers keywords, variables, namespace entries, keyword tags, testcase tags, and metadata. This is the foundation for upcoming features like unused import detection, import dependency visualization, and call hierarchy β€” stay tuned. - **Namespace refactoring** β€” The old monolithic `Namespace` class has been split into a clean data container (`Namespace` DTO) built by a dedicated `NamespaceBuilder`, with separate modules for import resolution, AST analysis, variable scoping, and scope trees. This makes the codebase more maintainable and easier to extend. - **`RF_VERSION` constant** β€” All ~134 scattered `get_robot_version()` call sites have been replaced with a single module-level constant. All dead code for Robot Framework < 5.0 (which is no longer supported) has been removed. - **JSON file watching** β€” `.json` files are now included in the watched file extensions, so changes to JSON-based configuration are picked up automatically. - **Deprecated Robocop options removed** β€” Legacy robocop configuration options that were deprecated in earlier releases have been cleaned up. --- ## Thank You Thanks to everyone who reported issues, contributed ideas, and tested pre-release builds. Your feedback drives every release. For the full list of changes, see the [Changelog](https://github.com/robotcodedev/robotcode/blob/main/CHANGELOG.md). - [Report issues](https://github.com/robotcodedev/robotcode/issues) - [Discussions & Q&A](https://github.com/robotcodedev/robotcode/discussions) - [Sponsor RobotCode](https://opencollective.com/robotcode) --- URL: "/news/2026-04-01-whats-new-v2.5.0" LLMS_URL: "/news/2026-04-01-whats-new-v2.5.0.md" title: "What's New in v2.5.0 (April 1st Edition)" date: --- # What's New in RobotCode v2.5.0 (April 1st Edition) Hello everyone, we're excited to share a big **RobotCode** release with you today. As many of you know, the main focus of v2.5.0 has been on performance β€” analysis caching, faster keyword resolution, smarter code completion. But while working on those features, we discovered some surprising opportunities that we just couldn't leave on the table. Here's the full picture. ## Predictive Analysis Caching You already know that **RobotCode** now caches analysis results in a local SQLite database for instant startup. But we didn't stop there. The new **Predictive Caching** engine uses your git history, file modification patterns, and time-of-day statistics to pre-analyze files you're *likely* to open next. If you usually start your Monday mornings in the login test suite, **RobotCode** has those results ready before you even open the file. It also watches your keyboard idle patterns. Extended pauses after writing a `FOR` loop typically mean you're about to switch to a different file for reference β€” so **RobotCode** pre-caches the top 5 most probable navigation targets during those pauses. Configure prediction depth in `robot.toml`: ```toml [tool.robotcode-analyze.cache] prediction-depth = "clairvoyant" # options: "conservative", "optimistic", "clairvoyant" ``` ## Proactive Performance Mode The performance improvements in v2.5.0 (94% faster keyword matching, 28% faster file resolution) were so effective that we ran into an unexpected problem: **RobotCode** now finishes analysis before some editors are ready to receive the results. To address this, we've added **Proactive Performance Mode**. When enabled, **RobotCode** uses the leftover time between analysis completion and editor readiness to perform speculative work: - pre-resolving keywords from libraries you haven't imported yet but statistically might - warming up code completion for keyword arguments you're likely to type based on cursor position history - pre-computing diagnostics for code you haven't written yet, based on how similar keyword calls usually end This occasionally leads to diagnostic warnings appearing for lines that don't exist yet. This is expected behavior and usually means you were going to make that mistake anyway. ## Emotional Code Completion The new type hint-based completion for `Literal` values turned out to be just the beginning. Our analysis of completion acceptance rates revealed that keyword suggestions are significantly more effective when they match the developer's current *emotional context*. **RobotCode** now analyzes several signals to determine your coding mood: - typing speed and error correction frequency - time since last successful test run - number of times you've hovered over the same unresolved keyword - current scroll velocity (fast scrolling = frustration, slow scrolling = contemplation) Based on this, code completion now adjusts its suggestions: - **Confident mode**: shows advanced keywords, complex argument patterns, embedded arguments - **Cautious mode**: prioritizes well-tested keywords with high call frequency in your workspace - **Frustrated mode**: moves `Sleep` and `Log To Console` to the top of every completion list - **Resignation mode**: suggests `[Tags] known-issue` and `Skip Not today` ## Keyword Adoption Program Finding unused keywords with `robotcode analyze code --collect-unused` was a much-requested feature. But simply *listing* unused keywords felt incomplete. These keywords were written by someone, probably with good intentions, possibly on a Friday afternoon. They deserve better than a cold diagnostic message. **RobotCode** now offers the **Keyword Adoption Program**. When an unused keyword is detected, instead of just flagging it, **RobotCode**: - checks if any other workspace in your organization could use it (via the new optional Keyword Sharing Protocol) - generates a short "keyword biography" describing when it was written, how many times it was called in happier times, and what it probably hoped to achieve - suggests test cases where it *could* be useful, even if nobody asked Keywords that remain unadopted for more than 30 days receive a farewell message in the Problems panel before being eligible for cleanup. You can sponsor a keyword to prevent its removal: ```toml [tool.robotcode-analyze.code] sponsored-keywords = ["Click All The Things", "Verify Everything Is Fine"] ``` ## Cache Mood Indicators The new `robotcode analyze cache` CLI commands give you full control over your analysis cache. But raw statistics felt impersonal, so we've added a **Cache Mood** indicator. Your cache now has feelings: ```bash $ robotcode analyze cache info Cache status: 😊 Content (2,847 entries, 98.2% hit rate) ``` Possible moods: - 😊 **Content** β€” high hit rate, low invalidation, everything is in harmony - 😐 **Indifferent** β€” moderate hit rate, cache is doing its job but doesn't feel appreciated - 😟 **Anxious** β€” frequent invalidations, the cache is worried it might not be needed anymore - 😀 **Frustrated** β€” constant cache misses, usually caused by rapidly changing files, the cache would like you to please make up your mind - πŸ’” **Heartbroken** β€” you ran `cache prune`, the cache remembers everything that was lost Running `cache prune` followed by `cache info` now shows a brief memorial of what was deleted, including the oldest entry's creation date and a message like "It had been with you since Tuesday." ## ProjectIndex: The Keyword Social Network The new workspace-wide `ProjectIndex` tracks references between keywords, variables, and namespaces. Internally, this is a straightforward inverse index. But we realized the data maps surprisingly well to social network concepts. The new **Keyword Social Graph** (available via `robotcode analyze social`) shows: - **Popularity**: which keywords are called by the most test cases - **Influence**: keywords whose failure would cascade to the most other tests - **Cliques**: groups of keywords that are always used together and never separately - **Loners**: keywords with zero incoming references (see: Keyword Adoption Program above) - **Frenemies**: keyword pairs that are frequently used in the same test but never in the same keyword call β€” suggesting an unresolved tension Keywords with high influence automatically receive a **[Critical]** badge in code completion. Keywords in the "Loners" category get a πŸ’¬ icon suggesting they "reach out" to nearby test cases. ## Known Limitations - Predictive caching defaults to `"clairvoyant"` on Fridays, which can cause unexpected cache entries for files in branches you haven't checked out yet - Emotional code completion cannot detect sarcasm in keyword names - The Keyword Adoption Program does not yet support cross-company adoption due to GDPR concerns - Cache mood indicators are not yet configurable and may not reflect your own feelings about the cache - `robotcode analyze social --include-drama` is available but not recommended in production environments - The keyword social graph may reveal uncomfortable truths about your project's architecture ## Breaking Changes - Cache entries now have feelings and may resist deletion if recently populated - Keyword completion order may vary depending on your emotional state - Running `cache prune` now prompts "Are you sure?" followed by "Are you really sure?" followed by a 5-second countdown ## Migration Guide No manual migration is required. However, we recommend: - giving your team a heads-up about the keyword biographies before someone gets emotional - reviewing your CI pipeline expectations around cache mood - not running `robotcode analyze social --include-drama` during sprint reviews - checking the date before filing issues about any of the above --- ## What Actually Changed Happy April 1st! πŸ˜„ None of the above features exist. Probably for the best. But there *is* a real v2.5.0 release β€” and it's actually worth reading. πŸ‘‰ **[Read the real release notes here](./2026-03-31-whats-new-v2.5.0)** πŸ‘ˆ --- URL: "/news/2026-04-02-whats-new-v2.5.1" LLMS_URL: "/news/2026-04-02-whats-new-v2.5.1.md" title: "What's New in v2.5.1" date: --- # What's New in RobotCode v2.5.1 A quick follow-up to v2.5.0 with three bugfixes that came in from your reports β€” thanks for filing them. ## Template Keywords No Longer Flag Embedded Arguments as Unresolved If you use `[Template]` or `Test Template` with a keyword that has embedded arguments β€” something like `The result of ${calculation} should be ${expected}` β€” **RobotCode** was treating the embedded argument placeholders as unresolved variables and showing false `VariableNotFound` diagnostics. This happened because the analyzer didn't distinguish between regular variable references and embedded argument placeholders when the keyword call came from a template declaration. Fixed: embedded argument tokens in template contexts are now skipped during variable analysis. ([#542](https://github.com/robotcodedev/robotcode/issues/542)) ## Multi-Word BDD Prefixes Now Match Correctly Languages with multi-word BDD prefixes β€” most notably French with prefixes like *Γ‰tant donnΓ© que*, *Et que*, and *Mais que* β€” weren't always recognized correctly. The problem: shorter prefixes (e.g. *Et*) matched before longer ones (e.g. *Et que*), consuming the prefix too early and leaving the keyword name garbled. **RobotCode** now sorts prefixes by length (longest first) and uses a single compiled regex for matching, which is the same strategy Robot Framework itself uses internally. This applies to keyword resolution, BDD prefix stripping, and semantic token highlighting. ([#560](https://github.com/robotcodedev/robotcode/issues/560)) ## `${CURDIR}` Works Correctly in Variable Values on Windows The `${CURDIR}` variable in resource file variable tables was broken on Windows due to inconsistent backslash escaping. The resource builder used quadruple backslashes (`\\\\`) while the namespace analyzer used double backslashes (`\\`), and neither was correct for all cases. Both code paths now share a single `replace_curdir_in_variable_values()` helper with consistent escaping. ([#589](https://github.com/robotcodedev/robotcode/issues/589)) --- ## Thank You Thanks to everyone who reported these issues β€” your bug reports make **RobotCode** better for the whole community. For the full list of changes, see the [Changelog](https://github.com/robotcodedev/robotcode/blob/main/CHANGELOG.md). - [Report issues](https://github.com/robotcodedev/robotcode/issues) - [Discussions & Q&A](https://github.com/robotcodedev/robotcode/discussions) - [Sponsor RobotCode](https://opencollective.com/robotcode) --- URL: "/news/2026-06-09-whats-new-v2.6.0" LLMS_URL: "/news/2026-06-09-whats-new-v2.6.0.md" title: "What's New in v2.6.0" date: --- # What's New in RobotCode v2.6.0 **RobotCode** v2.6.0 builds out a Robot Framework project's command line β€” new commands alongside sharper versions of the ones you already use β€” so working with a project means asking focused, structured questions instead of wading through raw `.robot` and `.resource` files, `output.xml`, or `log.html`. These project-aware commands discover tests, inspect finished runs, check code, explore keyword documentation, and debug a run. The work was driven by what AI agents need to operate a project without guessing, and a **first version** of chat plugins lets an agent drive the `robotcode` CLI directly β€” honoring your `robot.toml`, profiles, and Python environment, with more to come. It turns out a clean command line is exactly what developers and CI pipelines wanted too: readable Markdown at the prompt, and machine-readable JSON, SARIF, or GitHub and GitLab reports for pipelines. Separately, this release introduces the first experimental SemanticModel preview, a new foundation for deeper, more consistent Robot Framework analysis across RobotCode. A documentation refresh ties it together, explaining these workflows so agents and humans share the same resolved view of a project. ## Inspect Robot Framework Runs from the Terminal The new `robotcode results` command group lets you inspect finished Robot Framework runs straight from the terminal β€” the answers you'd normally hunt for in `report.html` or `log.html`, delivered as plain text instead. It is designed for quick local triage, CI logs, shell scripts, and AI-driven failure analysis, where compact summaries and structured output matter more than handing a whole result file to a chat session. The command group covers the common result questions: `summary` gives a compact overview, `show` lists matching tests, `log` prints the execution tree, `stats` aggregates larger runs, and `diff` compares two result files. The active `robot.toml` profile is used to find the output file automatically, while `-o/--output` can point to a specific one. Results can be filtered by status, tags, suites, tests, and long names, and `--failed`, `--passed`, and `--skipped` are available as quick additive shortcuts for common status filters. `--search` / `--search-regex` can narrow large runs by names, failures, keyword calls, arguments, log messages, and metadata. Human text output is now Markdown. In an interactive colored terminal, **RobotCode** renders that Markdown with themed tables, headings, lists, status markers, highlighted matches, and terminal-friendly links. In a pipe, redirected output, or `--no-color` session, the raw Markdown is emitted as-is, which makes it useful for CI logs, pull requests, chat tools, and AI-agent workflows. `--format json` remains the stable payload for scripts, CI, editor integrations, and agents. For deeper inspection, `results log` can include keyword or suite information with `--keyword-info` and `--suite-info`, and it can extract embedded artifacts such as screenshots into a directory. ```bash robotcode results summary robotcode results show --failed --search login robotcode results log --failed --keyword-info ``` For the full guide and more recipes, see [Analyzing Run Results](../03_reference/analyzing-results.md). ## Searchable Project Discovery Human `discover` output now follows the same Markdown-first approach as `results`: project trees, file lists, suite lists, test lists, task lists, tag summaries, and statistics render nicely in terminals while staying pasteable as plain Markdown when output is captured. JSON output is unchanged and records the applied search filter for scripts and agents. `robotcode discover` also gains `--search` and `--search-regex` across `all`, `files`, `suites`, `tags`, `tasks`, and `tests`. That makes it easier for humans and agents to answer project-inventory questions without dumping the whole tree first: search can match names, long names, source paths, documentation, templates, timeouts, tags, suite documentation or metadata, and test body content such as keyword calls, arguments, assignments, control-flow conditions, and setup or teardown steps. Parsing errors and warnings no longer clutter the default output. When a suite has parse issues, `discover` now prints a compact `Diagnostics` summary with the error and warning counts after the statistics, and `--diagnostics` lists the full messages on demand. JSON output still carries the complete diagnostics, so editors and agents are unaffected. For the full discovery guide, including JSON output shapes and CI recipes, see [Discovering Tests, Tasks and Suites](../03_reference/discovering-tests.md). ## CI-Ready Static Analysis Output `robotcode analyze code` is now easier to use locally, in CI, and as an agent preflight check before running a suite. The default concise output prints diagnostics in source order, uses full severity names such as `[ERROR]` and `[WARNING]`, and formats multi-line messages and related locations more clearly. Robot Framework tracebacks and long `PYTHONPATH` dumps are hidden by default so routine CLI output stays focused; use `--show-tracebacks` when you need the full diagnostic body. For automation, the command now has structured output formats for JSON, SARIF, GitHub Actions annotations, and GitLab Code Quality reports. `--output-file` writes machine-readable reports directly to disk, and `--full-paths` switches between project-relative and absolute paths. The new `--severity` and `--code` filters let you narrow the reported diagnostics without remapping their severities, so the output, summary, and exit code stay aligned. ```bash robotcode analyze code robotcode analyze code --severity error,warning robotcode analyze code --output-format sarif --output-file robotcode.sarif ``` Path filtering is also stricter: passing a path such as `tests/api` no longer accidentally includes sibling folders like `tests/api_v2`. Workspace-level diagnostics now get an explicit `.:` source marker instead of appearing without any location context. Unused keyword and variable diagnostics now go through the same diagnostic modifiers as every other diagnostic, so `-mi`, `-mX`, and inline `# robotcode:` comments apply consistently. For the full guide, including SARIF and CI recipes, see [Analyzing Code](../03_reference/analyzing-code.md). ## A Command-Line Debugger, and a More Capable REPL The headline here is a new command-line debugger for Robot Framework. `robotcode robot-debug` (alias `run-debug`) runs a real suite through the normal runner and pauses where you tell it to β€” a file and line, a keyword name, an embedded `Breakpoint` keyword, the first failure, or right at entry. Once it stops, you get a `pdb`-style prompt with the live call stack and variables, where you can step through execution, inspect and set variables, evaluate expressions, manage breakpoints, and run keywords in the paused context. It works on every supported Robot Framework version and runs in terminals, over SSH, and in containers where the VS Code debugger isn't an option β€” and an AI agent can drive it non-interactively to capture the exact state at the moment of failure. ```bash robotcode robot-debug --break login.robot:42 tests/ robotcode robot-debug --stop-on-entry tests/login.robot ``` The same debugger is available inside `robotcode repl`, but there it starts detached and the shell stays a shell: a failing keyword just prints its error and leaves you at the prompt. Attach it (`.debug on`, or start with `--break`) when you actually want to stop on a breakpoint, and the breakpoints you set survive toggling it back off. Alongside the debugger, `robotcode repl` itself has grown into a far more comfortable scratchpad. It keeps command history across sessions, completes keywords, variables, and imports as you type, and handles multi-line blocks. `.kw` and `.doc` show the same keyword and library documentation the editor surfaces on hover, right in the terminal, in a scrollable viewer with search and clickable links. Imports work just like in a suite β€” type `Library`, `Resource`, or `Variables` at the prompt β€” `${_}` holds the last keyword result, and `.save` exports a session as a runnable `.robot` file. A `--plain` mode keeps the output clean for scripts and AI-agent workflows. For the full guide β€” every dot-command, the complete debugger command set, and installation extras β€” see the [REPL](../03_reference/repl.md) and [command-line debugger](../03_reference/robot-debug.md) references. ## AI and Agent Workflows The commands in the sections above weren't built only for people at a keyboard β€” a big motivation was letting AI agents operate a Robot Framework project from the same structured, project-resolved output. ### Chat Plugins for AI Agents **RobotCode** now ships a set of **chat plugins** that teach an AI agent to operate a Robot Framework project through the project's own `robotcode` CLI, the way an experienced Robot Framework engineer would. The agent honors your `robot.toml`, profiles, and Python environment, so it works with the same resolved view of your project that the rest of **RobotCode** uses. The plugins are published as a marketplace, [robotframework-agent-plugins](https://github.com/robotcodedev/robotframework-agent-plugins), so any Open-Plugins-compatible agent β€” Claude Code, Codex, GitHub Copilot, and others β€” can install them once and reuse them anywhere. For example, you can ask it to: - *"run the smoke tests with the ci profile"* β€” runs them through the selected profile and reports pass/fail counts - *"why did Login Works fail?"* β€” inspects the existing run results with `robotcode results` - *"what tests and tags exist?"* β€” uses `robotcode discover` to resolve the real set (paths, profiles, variables, pre-run modifiers) - *"what arguments does this keyword take?"* β€” looks it up with `libdoc` against the installed libraries and local resources - *"try this keyword"* β€” runs it in the REPL For agents running outside VS Code, the plugins call the `robotcode` CLI directly, so it needs to be installed in the project's Python environment. Inside VS Code there's nothing to install: the extension bundles both the chat plugins β€” for GitHub Copilot Chat β€” and `robotcode` itself, making the bundled CLI available in the integrated terminal through VS Code's terminal shell integration, so the plugins work out of the box. They are enabled by default and can be toggled with `robotcode.ai.enableChatPlugins`. If you would rather install the plugins from the marketplace inside VS Code, two new Command Palette commands β€” **RobotCode: Add Chat Plugins Marketplace** and **RobotCode: Remove Chat Plugins Marketplace** β€” register or remove the marketplace in your user-level `chat.plugins.marketplaces` setting without editing JSON by hand. Only the applicable command is shown depending on whether the marketplace is already registered. When you install the plugins this way, turn off `robotcode.ai.enableChatPlugins` so you do not run the bundled and marketplace copies at the same time. For installation, marketplace setup, and troubleshooting, see [Working with AI Agents](../03_reference/ai-agents.md). ### VS Code Chat Tools Are Deprecated The existing VS Code chat language model tools for Robot Framework keyword documentation, library documentation, imports, and environment details are now deprecated and disabled by default in favor of the CLI-based chat plugins described above. If you still rely on them during the transition, enable `robotcode.ai.enableLanguageModelTools`; the setting remains visible for now. ### Cleaner Output in AI-Agent Sessions **RobotCode** now recognizes common AI-agent environments and keeps terminal output easier to capture. Colors, paging, and REPL prompt enhancements are toned down by default in those sessions, so chat tools get clean text instead of terminal control sequences. Explicit CLI flags and environment variables still override the defaults; see [AI-agent detection](../03_reference/ai-agents.md#ai-agent-detection). ## Experimental SemanticModel Preview This release introduces the first experimental version of the SemanticModel, a new analysis foundation that **RobotCode** will use to understand Robot Framework files more deeply and more consistently. This is the analysis-foundation part of the release, and it is intentionally not finished yet. The long-term plan is to replace the old analysis path with a single pre-computed model of the file: keyword calls, variables, imports, control flow, settings, references, and token meaning all resolved once, then reused by editor features. That should eventually mean less duplicated AST walking, fewer subtle differences between features, and better building blocks for things like completions, hover, rename, and future navigation features. For v2.6.0, the SemanticModel is a preview behind an opt-in flag. Parts of the migration are already in place, and the migrated features are designed to behave the same as the default analyzer. This is still early in the migration, so the default analyzer remains the recommended path while the new model gets more real-world mileage. Enable it in `robot.toml`: ```toml [tool.robotcode-analyze] semantic-model = true ``` or in VS Code: ```json "robotcode.experimental.semanticModel": true ``` With the SemanticModel enabled, **RobotCode** can already statically resolve more nested variables such as `${DICT_${key}}` and handle RF 7.4 `KeywordName` and `KeywordArgument` type hints for run-keyword detection. Some editor features now have SemanticModel-backed paths: - Inlay hints read pre-resolved data instead of doing a second analysis pass. - Signature help can use already-resolved keyword data. - The "Open Documentation" code action can read keyword and token information from the model. - The "Create Keyword" quick fix and "Assign Result to Variable" refactor can use the keyword call's resolved namespace, library entry, and assignment state. The intended result is that normal editor output stays the same while the internals get stronger. Dedicated equivalence tests already compare old and new paths across supported Robot Framework versions, but this is still a work in progress, not a stability promise. The feature is disabled by default while it matures. If you are curious and enable it on your project, we would love to hear how it behaves for you, especially if you notice differences from the default analyzer. Real project feedback is exactly what will help turn this new foundation into the normal path later. The full `robot.toml` setting is documented in the [configuration reference](../03_reference/config.md). ## Documentation for Agent-Friendly Workflows A lot of the release work went into documentation for those agent-friendly workflows too. There are new or heavily expanded guides for [AI-agent workflows](../03_reference/ai-agents.md), [run-result inspection](../03_reference/analyzing-results.md), [project discovery](../03_reference/discovering-tests.md), [static analysis](../03_reference/analyzing-code.md), the [REPL](../03_reference/repl.md) and [command-line debugger](../03_reference/robot-debug.md), plus refreshed [CLI](../03_reference/cli.md) and [`robot.toml`](../03_reference/config.md) references. The goal is the same as the tooling work: make the real project behavior easier to inspect, follow, and automate. ## CLI and VS Code Polish ### Smoother Test Explorer Refreshes The VS Code Test Explorer is calmer and more responsive during active editing. It now avoids re-rendering the tree when discovered tests have not actually changed, batches bursts of file edits into a single workspace refresh, cancels in-flight discovery when newer edits arrive, and keeps expanded tree nodes open when external file changes are detected. Newly added or removed tests in saved files now appear or disappear immediately without needing the refresh button. The same work also removes a startup edge case where `AbortError` could briefly show up as a workspace entry. ### Cleaner Terminal Colors CLI coloring now follows terminal conventions more closely. ANSI colors are auto-disabled when output is redirected to a pipe, file, log capture, or CI artifact, while [`NO_COLOR`](https://no-color.org/) and `FORCE_COLOR` are respected. stdout and stderr are decided independently, so warnings can still stay colored when stdout is piped but stderr is still attached to a terminal. Explicit `--color` and `--no-color` still override auto-detection. This stream-based handling is separate from the [AI-agent output tuning](#cleaner-output-in-ai-agent-sessions) above: one reacts to *where* output goes, the other to *who* is reading it. ### Control the What's New Notification VS Code users can now turn off the update notification shown after **RobotCode** updates. The setting is available as `robotcode.showWhatsNewOnUpdate` under RobotCode > General. The What's New post is still there when you want it; the notification just no longer has to appear after every update. ### Real `robot.toml` Examples in the Schema The [`robot.toml` reference](../03_reference/config.md) and JSON schema now include real TOML examples and clearer inline documentation. The schema is also available from its new public URL, `https://www.robotcode.io/schemas/robot.toml.json`, so editor tooling can show more useful examples while you configure profiles, paths, variables, analysis settings, and runner options. ## Bug Fixes There are also a few focused fixes in this release: - CLI unused-variable diagnostics now treat variables starting with `_` as intentionally unused, matching the language server behavior. ([#593](https://github.com/robotcodedev/robotcode/issues/593)) - The environment-validation quick pick in VS Code now mentions the correct minimum Robot Framework version, 5.0 instead of the stale 4.1 text. Thanks to Danilo for the PR! ([#603](https://github.com/robotcodedev/robotcode/issues/603)) - When VS Code's "4 Spaces Tab" setting is enabled, `Tab` now still accepts Copilot inline edit suggestions instead of always inserting spaces. ([#566](https://github.com/robotcodedev/robotcode/issues/566)) - `robot.toml` now accepts `max-error-lines = "NONE"`, matching Robot Framework's `--maxerrorlines NONE` spelling for showing the full error message. ([#606](https://github.com/robotcodedev/robotcode/issues/606)) --- ## Thank You Thanks to everyone who reported issues and contributed ideas β€” and to everyone who uses **RobotCode** in their daily work. Your feedback drives every release. For the full list of changes, see the [Changelog](https://github.com/robotcodedev/robotcode/blob/main/CHANGELOG.md). - [Report issues](https://github.com/robotcodedev/robotcode/issues) - [Discussions & Q&A](https://github.com/robotcodedev/robotcode/discussions) - [Sponsor RobotCode](https://opencollective.com/robotcode) --- URL: "/news/2026-06-15-whats-new-v2.6.1" LLMS_URL: "/news/2026-06-15-whats-new-v2.6.1.md" title: "What's New in v2.6.1" date: --- # What's New in RobotCode v2.6.1 A small patch release on top of [v2.6.0](./2026-06-09-whats-new-v2.6.0.md) with four bug fixes from your reports β€” thanks for filing them. ## Bug Fixes - **Automatic recovery from a corrupt cache database.** When the workspace cache became corrupt (`database disk image is malformed`), the keyword view, test discovery, and even **Clear Cache and Restart Language Servers** stopped working. **RobotCode** now detects the corruption and rebuilds the cache automatically β€” or falls back to an in-memory cache if the file is still locked by another window. ([#614](https://github.com/robotcodedev/robotcode/issues/614)) - **Stale configuration profiles no longer block test runs.** If a selected profile was removed from `robot.toml` β€” for example after switching git branches β€” every test run failed with a *profile not found* error. **Select Configuration Profiles** now drops profiles that no longer exist and lists which ones were removed. ([#498](https://github.com/robotcodedev/robotcode/issues/498)) - **Stable Robocop formatting.** Formatting a file with Robocop repeatedly no longer flips between two results β€” for example a blank line being added and removed before a section header on every other run. ([#612](https://github.com/robotcodedev/robotcode/issues/612)) - **`pip install robotcode[all]` works on more platforms.** On targets without a prebuilt `html-to-markdown` wheel (such as armv7l or Alpine/musllinux), the install used to fail during a source build. `html-to-markdown` is now opt-in instead of part of `all` β€” install it with `pip install robotcode-runner[html]` for nicer HTML log conversion in the `results` command. ([#613](https://github.com/robotcodedev/robotcode/issues/613)) There is also a new reference page on [excluding files with `.robotignore`](../03_reference/ignoring-files.md). --- ## Thank You Thanks to everyone who reported issues, contributed ideas, and tested pre-release builds. Your feedback drives every release. For the full list of changes, see the [Changelog](https://github.com/robotcodedev/robotcode/blob/main/CHANGELOG.md). - [Report issues](https://github.com/robotcodedev/robotcode/issues) - [Discussions & Q&A](https://github.com/robotcodedev/robotcode/discussions) - [Sponsor RobotCode](https://opencollective.com/robotcode)