robot-framework
Skill2 starsChanged 3 months agoMITView on GitHub
Production-grade skill for Robot Framework keyword-driven testing. Covers project structure, keywords, variables, libraries (Selenium, Requests, Database), resources, setup/teardown, tags, CLI execution, and CI/CD integration.
- Installs packages
Files
Robot Framework Skill
Description
Comprehensive skill for Robot Framework, the leading keyword-driven test automation framework in Python. Covers project structure, custom and built-in keywords, variable scopes, resource and variable files, library integration (Selenium, Requests, Database), setup/teardown patterns, tag-based execution, command-line options, and CI/CD integration.
Table of Contents
- Project Setup
- Test Case Syntax
- Keywords
- Variables
- Libraries
- Resource & Variable Files
- Setup & Teardown
- Tags
- Execution & CLI
- CI/CD Integration
- Best Practices Checklist
- Common Pitfalls
- References
When to Invoke
- Creating or refactoring a Robot Framework test suite
- Writing keyword-driven tests for web, API, or database validation
- Structuring a Robot Framework project with resources and libraries
- Implementing custom keywords in Python or Robot syntax
- Managing variables across different scopes (test, suite, global)
- Integrating SeleniumLibrary, RequestsLibrary, or DatabaseLibrary
- Configuring setup/teardown at test, suite, or global level
- Using tags to organize and filter test execution
- Running tests via CLI with custom options and listeners
- Integrating Robot Framework into Jenkins, GitHub Actions, or GitLab CI
1. Project Setup
Directory Layout
robot-project/
tests/
api/
login_api.robot
users_api.robot
ui/
login_ui.robot
checkout_ui.robot
resources/
keywords/
common.robot
api_keywords.robot
ui_keywords.robot
pages/
login_page.robot
home_page.robot
variables/
global_variables.py
test_data.yaml
locators/
login_locators.yaml
libraries/
CustomLibrary.py
config/
environments.yaml
results/
requirements.txt
run.shrequirements.txt
robotframework>=6.1.0
robotframework-seleniumlibrary>=6.1.0
robotframework-requests>=0.9.5
robotframework-databaselibrary>=1.3.0
robotframework-pabot>=2.15.0Installation
pip install -r requirements.txt2. Test Case Syntax
Basic Structure
*** Settings ***
Documentation Test suite for user login functionality
Resource ../resources/keywords/common.robot
Test Setup Open Browser To Login Page
Test Teardown Close Browser
*** Test Cases ***
Valid Login
[Documentation] Verify that a valid user can log in successfully
[Tags] smoke regression api
Input Username ${VALID_USER}
Input Password ${VALID_PASSWORD}
Click Login Button
Welcome Page Should Be Open
Invalid Login With Wrong Password
[Documentation] Verify login fails with incorrect password
[Tags] regression negative
Input Username ${VALID_USER}
Input Password wrongpassword
Click Login Button
Error Message Should Be Visible Invalid credentialsBDD-Style Syntax
*** Test Cases ***
User Can Add Item To Cart
Given User Is Logged In
When User Adds Product "Headphones" To Cart
Then Cart Should Contain "Headphones"
And Cart Total Should Be "$99.99"3. Keywords
Built-in Keywords
*** Test Cases ***
Built-in Examples
${result} = Evaluate 2 + 2
Should Be Equal As Numbers ${result} 4
${list} = Create List apple banana cherry
Should Contain ${list} banana
${dict} = Create Dictionary name=John age=30
Dictionary Should Contain Key ${dict} name
Run Keyword If ${result} > 3 Log Result is greater than 3
Run Keyword Unless ${result} == 4 Fail Unexpected result
Wait Until Keyword Succeeds 5x 1s Check Element Is Visible id:submitUser-Defined Keywords (Robot Syntax)
*** Keywords ***
Input Username
[Arguments] ${username}
[Documentation] Enters the given username into the username field
Wait Until Element Is Visible ${LOGIN.USERNAME_FIELD}
Input Text ${LOGIN.USERNAME_FIELD} ${username}
Input Password
[Arguments] ${password}
Input Text ${LOGIN.PASSWORD_FIELD} ${password}
Click Login Button
Click Button ${LOGIN.SUBMIT_BUTTON}
Welcome Page Should Be Open
Location Should Be ${WELCOME_URL}
Page Should Contain Welcome
Login With Credentials
[Arguments] ${username} ${password}
Input Username ${username}
Input Password ${password}
Click Login ButtonCustom Keywords in Python
# libraries/CustomLibrary.py
from robot.api.deco import keyword
import hashlib
class CustomLibrary:
ROBOT_LIBRARY_SCOPE = "GLOBAL"
def __init__(self):
self.session = None
@keyword("Generate MD5 Hash")
def generate_md5(self, text: str) -> str:
"""Generate MD5 hash of the given text."""
return hashlib.md5(text.encode()).hexdigest()
@keyword("Format Currency")
def format_currency(self, amount: float, symbol: str = "$") -> str:
"""Format amount as currency string."""
return f"{symbol}{amount:,.2f}"
@keyword("Validate Email Format")
def validate_email(self, email: str) -> bool:
"""Check if email format is valid."""
import re
pattern = r"^[^@]+@[^@]+\.[^@]+$"
return bool(re.match(pattern, email))Keyword Arguments
*** Keywords ***
Create User Via API
[Arguments] ${name} ${email} ${role}=user ${status}=active
${payload} = Create Dictionary
... name=${name}
... email=${email}
... role=${role}
... status=${status}
${response} = POST On Session api /users json=${payload}
Should Be Equal As Strings ${response.status_code} 201
RETURN ${response.json()['id']}Keyword Teardown
*** Keywords ***
Create Temporary File
[Arguments] ${content}
[Teardown] Remove File ${path}
${path} = Join Path ${TEMPDIR} temp.txt
Create File ${path} ${content}
RETURN ${path}4. Variables
Variable Scopes
| Prefix | Scope | Example |
${VAR} | Global / Test case | ${VALID_USER} |
@{LIST} | List variable | @{USERS} |
&{DICT} | Dictionary variable | &{CREDENTIALS} |
$${VAR} | Environment variable | $${PATH} |
%{VAR} | Operating system variable | %{HOME} |
Scalar Variables
*** Variables ***
${URL} https://api.example.com
${BROWSER} chrome
${TIMEOUT} 10
${VALID_USER} testuser@example.com
${VALID_PASSWORD} TestPassword123!List Variables
*** Variables ***
@{BROWSERS} chrome firefox edge
@{HTTP_METHODS} GET POST PUT DELETE*** Test Cases ***
Test All Browsers
FOR ${browser} IN @{BROWSERS}
Open Browser ${URL} ${browser}
Log In With Valid Credentials
Close Browser
ENDDictionary Variables
*** Variables ***
&{VALID_CREDENTIALS} username=testuser password=TestPass123
&{HEADERS} Content-Type=application/json Accept=application/json*** Test Cases ***
Login With Dictionary Credentials
Input Text ${LOGIN.USERNAME} ${VALID_CREDENTIALS}[username]
Input Text ${LOGIN.PASSWORD} ${VALID_CREDENTIALS}[password]Variable Files (Python)
# variables/global_variables.py
import os
URL = os.environ.get("BASE_URL", "https://staging.example.com")
BROWSER = os.environ.get("BROWSER", "chrome")
TIMEOUT = int(os.environ.get("TIMEOUT", "10"))
VALID_USER = os.environ.get("TEST_USER", "testuser@example.com")
VALID_PASSWORD = os.environ.get("TEST_PASSWORD", "TestPassword123!")*** Settings ***
Variables ../variables/global_variables.pyVariable Files (YAML)
# variables/test_data.yaml
users:
admin:
username: admin@example.com
password: AdminPass123
role: administrator
editor:
username: editor@example.com
password: EditorPass456
role: editor*** Settings ***
Variables ../variables/test_data.yaml
*** Test Cases ***
Login As Admin
Log In ${users}[admin][username] ${users}[admin][password]5. Libraries
SeleniumLibrary (UI Testing)
*** Settings ***
Library SeleniumLibrary timeout=10 implicit_wait=2
*** Keywords ***
Open Browser To Login Page
Open Browser ${URL} ${BROWSER}
Maximize Browser Window
Set Selenium Speed 0.5s
Go To ${URL}/login
Title Should Be Login
Wait And Click Element
[Arguments] ${locator}
Wait Until Element Is Visible ${locator} timeout=${TIMEOUT}
Click Element ${locator}
Capture Screenshot On Failure
[Arguments] ${filename}
Capture Page Screenshot ${filename}RequestsLibrary (API Testing)
*** Settings ***
Library RequestsLibrary
*** Keywords ***
Create API Session
Create Session api ${URL} headers=${HEADERS}
${token} = Get Auth Token
Set To Dictionary ${HEADERS} Authorization=Bearer ${token}
Get Auth Token
${payload} = Create Dictionary username=${VALID_USER} password=${VALID_PASSWORD}
${response} = POST On Session api /auth/login json=${payload}
Should Be Equal As Strings ${response.status_code} 200
RETURN ${response.json()['token']}
Get User By ID
[Arguments] ${user_id}
${response} = GET On Session api /users/${user_id}
Should Be Equal As Strings ${response.status_code} 200
RETURN ${response.json()}DatabaseLibrary (Database Testing)
*** Settings ***
Library DatabaseLibrary
*** Keywords ***
Connect To Test Database
Connect To Database
... pymysql
... ${DB_NAME}
... ${DB_USER}
... ${DB_PASSWORD}
... ${DB_HOST}
... ${DB_PORT}
Verify User Exists In Database
[Arguments] ${email}
${result} = Query SELECT id FROM users WHERE email = '${email}'
Should Not Be Empty ${result}Built-in Libraries Summary
| Library | Purpose |
BuiltIn | Core keywords (log, evaluate, run keyword if, etc.) |
Collections | List/dictionary operations |
DateTime | Date and time manipulation |
OperatingSystem | File system, environment variables |
Process | Run external processes |
Screenshot | Take screenshots |
String | String manipulation |
XML | XML parsing and validation |
6. Resource & Variable Files
Resource File Structure
# resources/keywords/common.robot
*** Settings ***
Documentation Common keywords used across test suites
Library SeleniumLibrary
Library RequestsLibrary
Variables ../variables/global_variables.py
*** Keywords ***
Log In With Valid Credentials
Input Text ${LOGIN.USERNAME} ${VALID_USER}
Input Text ${LOGIN.PASSWORD} ${VALID_PASSWORD}
Click Button ${LOGIN.SUBMIT}
Welcome Page Should Be Open
Log In
[Arguments] ${username} ${password}
Input Text ${LOGIN.USERNAME} ${username}
Input Text ${LOGIN.PASSWORD} ${password}
Click Button ${LOGIN.SUBMIT}
Log Out
Click Element ${NAV.LOGOUT}
Page Should Contain You have been logged outPage Object Pattern
# resources/pages/login_page.robot
*** Variables ***
${LOGIN.URL} /login
${LOGIN.USERNAME} id:username
${LOGIN.PASSWORD} id:password
${LOGIN.SUBMIT} id:submit-button
${LOGIN.ERROR} css:.error-message
${LOGIN.SUCCESS} css:.success-message
*** Keywords ***
Open Login Page
Go To ${BASE_URL}${LOGIN.URL}
Wait Until Element Is Visible ${LOGIN.USERNAME}
Input Username
[Arguments] ${username}
Input Text ${LOGIN.USERNAME} ${username}
Input Password
[Arguments] ${password}
Input Text ${LOGIN.PASSWORD} ${password}
Submit Login Form
Click Button ${LOGIN.SUBMIT}
Error Message Should Be Visible
[Arguments] ${expected_message}
Wait Until Element Is Visible ${LOGIN.ERROR}
Element Should Contain ${LOGIN.ERROR} ${expected_message}Importing Resources
*** Settings ***
Resource ../resources/keywords/common.robot
Resource ../resources/pages/login_page.robot
Resource ../resources/pages/home_page.robot
Variables ../variables/global_variables.py
Variables ../variables/test_data.yaml7. Setup & Teardown
Levels
*** Settings ***
# Suite-level: runs once per suite file
Suite Setup Connect To Test Database
Suite Teardown Disconnect From Database
# Test-level: runs before/after each test case
Test Setup Open Browser To Login Page
Test Teardown Close Browser
# Task-level (in RPA): runs before/after each task
Task Setup Log In As Admin
Task Teardown Log OutNamed Setup/Teardown
*** Keywords ***
Prepare Test Environment
Connect To Database
Clean Test Data
Seed Test Users
Clean Up Test Environment
Rollback Transactions
Disconnect From Database
*** Settings ***
Suite Setup Run Keywords Prepare Test Environment AND Log Suite setup complete
Suite Teardown Run Keywords Clean Up Test Environment AND Log Suite teardown completeConditional Teardown
*** Test Cases ***
Create Order Test
[Setup] Log In As Admin
[Teardown] Run Keyword If Test Failed Cancel Order ${ORDER_ID}
${ORDER_ID} = Create Order
Verify Order Exists ${ORDER_ID}8. Tags
Tag Syntax
*** Test Cases ***
Valid Login
[Tags] smoke regression critical ui
... jira:PROJ-123
Login With Credentials ${VALID_USER} ${VALID_PASSWORD}
Welcome Page Should Be OpenTagging at Suite Level
*** Settings ***
Default Tags regression api
Force Tags sprint-42Tag Patterns in CLI
# Include only smoke tests
robot --include smoke tests/
# Exclude slow tests
robot --exclude slow tests/
# Include smoke AND critical
robot --include smokeANDcritical tests/
# Include smoke OR critical
robot --include smokeORcritical tests/
# Exclude wip AND debug
robot --exclude wipORdebug tests/
# Combine include and exclude
robot --include regression --exclude slow tests/
# Tag patterns with wildcards
robot --include sprint* tests/Tagging via Python Listener
# listeners/TagListener.py
from robot.api import SuiteVisitor
class TagListener(SuiteVisitor):
def start_suite(self, suite):
for test in suite.tests:
if "api" in suite.name.lower():
test.tags.add("api-suite")9. Execution & CLI
Basic Execution
# Run all tests in directory
robot tests/
# Run specific test file
robot tests/ui/login.robot
# Run specific test case
robot --test "Valid Login" tests/ui/login.robot
# Run multiple test suites
robot tests/ui/ tests/api/Output Options
# Custom output directory
robot --outputdir results/ tests/
# Custom report names
robot --output results/output.xml --report results/report.html --log results/log.html tests/
# Generate only XML (for CI)
robot --output results/output.xml --report NONE --log NONE tests/
# Set log level
robot --loglevel DEBUG tests/Variable Overrides
# Override variables from CLI
robot --variable BROWSER:firefox --variable URL:https://staging.example.com tests/
# Variable file
robot --variablefile variables/staging.py tests/
# Multiple variable files
robot --variablefile variables/common.py --variablefile variables/staging.py tests/Parallel Execution (pabot)
# Run tests in parallel across 4 processes
pabot --processes 4 tests/
# Parallel with custom output
pabot --processes 4 --outputdir results/ tests/
# Parallel by suite
pabot --processes 4 --pabotlib tests/Dry Run
# Validate syntax without executing keywords
robot --dryrun tests/Listeners
# Custom listener for custom reporting
robot --listener listeners.AllureListener tests/10. CI/CD Integration
GitHub Actions
# .github/workflows/robot-tests.yml
name: Robot Framework Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
selenium:
image: selenium/standalone-chrome
ports:
- 4444:4444
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install dependencies
run: pip install -r requirements.txt
- name: Run Robot Framework tests
run: |
robot \
--variable BROWSER:headlesschrome \
--variable SELENIUM_URL:http://localhost:4444/wd/hub \
--outputdir results/ \
--exclude wip \
tests/
- name: Upload results
if: always()
uses: actions/upload-artifact@v4
with:
name: robot-results
path: results/Jenkins Pipeline
pipeline {
agent any
stages {
stage('Test') {
steps {
sh '''
robot \
--variable ENV:staging \
--outputdir results/ \
--exclude not_ready \
tests/
'''
}
}
}
post {
always {
robot outputPath: 'results/'
}
}
}GitLab CI
stages:
- test
robot-tests:
stage: test
image: python:3.11
services:
- selenium/standalone-chrome
script:
- pip install -r requirements.txt
- robot --outputdir results/ --exclude wip tests/
artifacts:
when: always
paths:
- results/
reports:
junit: results/output.xml11. Best Practices Checklist
- Use Page Object pattern: locators in dedicated
.robotfiles, logic in keyword files - Keep test cases short and focused: one assertion per test
- Use BDD naming:
Given/When/Thenin test case names - Extract reusable keywords to resource files
- Use variables for all dynamic data (URLs, credentials, timeouts)
- Store sensitive data in environment variables, never in repo
- Use tag expressions to organize by layer (
ui,api,db) and priority (smoke,regression) - Implement setup/teardown at the lowest possible scope
- Use
Wait Until Keyword Succeedsfor flaky operations - Add
[Documentation]to every test case and keyword - Use
[Arguments]typing for keyword parameters - Return values from keywords using
RETURN(orReturn From Keywordin older versions) - Use
Run Keyword And Ignore Errorfor non-critical steps - Implement custom Python libraries for complex logic
- Use
pabotfor parallel execution in CI - Generate JUnit-compatible output for CI integration
- Keep locators in YAML or dedicated files, not inline in keywords
- Use
Set Selenium Speedonly for debugging, not in CI - Implement
Listenerfor custom reporting (Allure, TestRail, etc.) - Version control
.robotfiles; excluderesults/directory
12. Common Pitfalls
| Problem | Cause | Solution |
Variable not found | Wrong scope or missing import | Check *** Variables *** section or resource import |
Keyword not found | Missing Resource or Library import | Verify *** Settings *** imports |
Element not found | Timing issue or wrong locator | Use Wait Until Element Is Visible with explicit timeout |
Suite setup failed | Previous test left dirty state | Implement robust suite teardown |
| Slow test execution | Sleep or implicit waits | Replace Sleep with explicit waits |
| Duplicate keywords | Same name in multiple resources | Use resource namespacing or unique names |
| Hardcoded credentials | Values in .robot files | Move to environment variables or encrypted files |
| Brittle locators | XPath with dynamic IDs | Use data-testid attributes or CSS classes |
| Missing teardown on failure | Teardown not running after exception | Use Run Keyword If Test Failed in teardown |
| Parallel execution conflicts | Shared state between processes | Use pabotlib or isolate test data per process |
| Log pollution | Too many screenshots | Capture only on failure or for specific steps |
FOR loop scope issues | Variables leaking between iterations | Use END and localize loop variables |
13. References
- Robot Framework User Guide
- SeleniumLibrary Documentation
- RequestsLibrary Documentation
- DatabaseLibrary Documentation
- Robot Framework Built-in Keywords
- pabot — Parallel Executor
- Robot Framework Listener Interface
- Related skills:
selenium-automation,behave-bdd,playwright-best-practices,postman
In this repository45 other files it gives its agents.
- AGENTS.mdAGENTS.md
- allure-reportsSkill
- android-nativeSkill
- appian-lowcodeSkill
- appium-mobileSkill
- behave-bddSkill
- BiDiWave Cross-BrowserSkill
- BiDiWave Network InterceptionSkill
- CDPWave DebuggingSkill
- CDPWave TestingSkill
- db2-oracleSkill
- ebook-writerSkill
- flask-apiSkill
- flet-desktopSkill
- google-crawling-indexingSkill
- google-ranking-appearanceSkill
- google-seo-fundamentalsSkill
- google-seo-monitoringSkill
- jinja2-templatesSkill
- jmeter-load-testingSkill
- k6-load-testingSkill
- karate-api-testingSkill
- octane-almSkill
- paramiko-sshSkill
- postman-api-automationSkill
- prestashop-moduleSkill
- prompt-engineering-best-practicesSkill
- pytest-advancedSkill
- salesforce-devSkill
- sonarqube-quality-gatesSkill
- sql-serverSkill
- Skill NameSkill
- testcontainersSkill
- wave-ecosystem-guideSkill
- WaveXis AccessibilitySkill
- WaveXis CI/CD IntegrationSkill
- wavexis-cli-automationSkill
- wavexis-mcp-agent-integrationSkill
- WaveXis Network TestingSkill
- WaveXis Performance AuditSkill
- WaveXis Session RecordingSkill
- WaveXis Web ScrapingSkill
- webdriverioSkill
- wordpress-themesSkill
- xctest-iosSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

