Skip to content

Practical — Full UI Framework

Compact but real end-to-end framework example using Robot Framework + Browser (Playwright) + Python helpers.

For progressive learning, start with UI Testing — Step by Step.

Structure

ui-tests/
├── pyproject.toml
├── libraries/
│   ├── DataFactory.py
│   └── ScreenshotHelper.py
├── resources/
│   ├── common.resource
│   └── pages/
│       ├── login_page.resource
│       ├── dashboard_page.resource
│       └── settings_page.resource
└── tests/
    ├── login/login_tests.robot
    └── e2e/user_settings_flow.robot

pyproject.toml

[project]
name = "ui-tests"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
  "robotframework>=7.0",
  "robotframework-browser>=19.0",
  "faker>=30.0",
]

Install and bootstrap browsers:

uv sync
uv run rfbrowser init

Python helpers

libraries/DataFactory.py

import uuid
from faker import Faker
from robot.api.deco import keyword, library

fake = Faker()

@library(scope="GLOBAL")
class DataFactory:
    @keyword("Generate Unique Username")
    def username(self) -> str:
        return f"user-{uuid.uuid4().hex[:8]}"

    @keyword("Generate User Data")
    def user_data(self) -> dict:
        u = self.username()
        return {"name": fake.name(), "username": u, "email": f"{u}@example.com"}

libraries/ScreenshotHelper.py

from datetime import datetime, timezone
from robot.api.deco import keyword, library
from robot.libraries.BuiltIn import BuiltIn

@library(scope="SUITE")
class ScreenshotHelper:
    @keyword("Capture Named Screenshot")
    def capture(self, context: str = "failure") -> str:
        ts = datetime.now(timezone.utc).strftime("%Y%m%d_%H%M%S")
        fn = f"results/screenshots/{context}_{ts}.png"
        BuiltIn().get_library_instance("Browser").take_screenshot(filename=fn)
        return fn

Resources

resources/common.resource

*** Settings ***
Library    Browser
Library    ../libraries/DataFactory.py
Library    ../libraries/ScreenshotHelper.py

*** Variables ***
${APP_URL}         https://demo.example.com
${BROWSER_TYPE}    chromium
${HEADLESS}        ${True}

*** Keywords ***
Open Test Browser
    New Browser    ${BROWSER_TYPE}    headless=${HEADLESS}
    New Context    viewport={'width': 1280, 'height': 720}
    New Page       ${APP_URL}
    Set Browser Timeout    10s

Close Test Browser
    Close Browser    ALL

Capture On Failure
    Capture Named Screenshot    test-failure

resources/pages/login_page.resource

*** Settings ***
Library    Browser

*** Variables ***
${LOC_USER}       [data-testid="login-username"]
${LOC_PASS}       [data-testid="login-password"]
${LOC_SUBMIT}     [data-testid="login-submit"]
${LOC_ERROR}      [data-testid="login-error"]
${LOC_WELCOME}    [data-testid="welcome-message"]

*** Keywords ***
Login As User
    [Arguments]    ${username}    ${password}
    Go To    ${APP_URL}/login
    Fill Text    ${LOC_USER}    ${username}
    Fill Text    ${LOC_PASS}    ${password}
    Click    ${LOC_SUBMIT}

Login Should Succeed
    Wait For Elements State    ${LOC_WELCOME}    visible    timeout=5s

Login Error Should Be Visible
    Wait For Elements State    ${LOC_ERROR}    visible    timeout=5s

Tests

tests/login/login_tests.robot

*** Settings ***
Resource          ../../resources/common.resource
Resource          ../../resources/pages/login_page.resource
Suite Setup       Open Test Browser
Suite Teardown    Close Test Browser
Test Teardown     Capture On Failure

*** Test Cases ***
Valid Login
    [Tags]    smoke
    Login As User    testuser    secretpass123
    Login Should Succeed

Invalid Password
    [Tags]    negative
    Login As User    testuser    wrong
    Login Error Should Be Visible

tests/e2e/user_settings_flow.robot

*** Settings ***
Resource          ../../resources/common.resource
Resource          ../../resources/pages/login_page.resource
Suite Setup       Open Test Browser
Suite Teardown    Close Test Browser
Test Teardown     Capture On Failure

*** Test Cases ***
User Updates Display Name
    [Tags]    smoke    e2e
    Login As User    testuser    secretpass123
    Login Should Succeed
    ${name}=    Generate Unique Username
    Log    Updated display name: ${name}    INFO

Run

uv run robot --outputdir results --include smoke tests/
uv run robot --outputdir results --variable HEADLESS:False tests/login/
uv run pabot --processes 4 --outputdir results tests/

Flow

tests -> page resources -> Browser library + Python helpers