This framework leverages Agentic AI to autonomously execute frontend test cases written in natural English and dynamically generate test automation code based on a library of pre-defined tools and agents.
- Mandatory Pre Read
- Project Structure
- Config Usage in Test Cases
- Onboarding Checklist for a New Agent
- Tool Onboarding Process
- Locator Best Practices
- Additional Requirements
- Quick Start
- Key Points to Consider
- Contributing
- Acknowledgements
- Issues and Support
leap-agentic/
βββ src/
β βββ core_agentic/
β β βββ agentic.py # Core AI modules and LLM logic
β β βββ agentic_base.py # Hooks, setup/teardown, and workflow support
β β βββ test_trial.py # Playground for English-based test execution
β β βββ run_configs.py # Configs to control execution (e.g., channel, LLM model)
β βββ main/
β βββ agent_group/ # Folder for each agent group (e.g., redBus Home Page)
β β βββ agent/ # Folder for each agent (e.g., Search Form)
β β β βββ agent_details.py # Agent metadata (Name, Description)
β β β βββ tools/ # Tools available for the agent
β β β βββ definitions/ # Abstract tool signatures for AI
β β β β βββ agent_locator_tools.py # Web element abstracts
β β β β βββ agent_function_tools.py # Business flow abstracts
β β β βββ implementation/ # Platform-specific implementations
β β β βββ android.py
β β β βββ ios.py
β β β βββ mweb.py
β β β βββ dweb.py
β βββ por/ # Page Object Repository (Singleton pattern)
β β βββ por_agent_group.py # File for agent group comprising agent objects
β β βββ por_master.py # Master repository with all agent group PORs
β βββ utilities/
β βββ helper/ # Frontend Automation "Super Helper"
β βββ helper_definition.py # Abstract methods/capabilities shared with AI
β βββ helper_common_implementation.py # Cross-platform logic & internal framework tools
β βββ helper_apps_implementation.py # App-specific logic (Gestures, Contexts)
β βββ helper_browser_implementation.py # Web-specific logic (Cookies, Window handles)
β βββ resources/
β βββ configs/
β βββ common.yaml # Cross-platform common configs
β βββ mweb.yaml # MWeb-specific config
β βββ dweb.yaml # DWeb-specific config
β βββ android.yaml # Android-specific config
β βββ ios.yaml # iOS-specific config
βββ credentials.json # Your API keys (not tracked in git)
βββ credentials.json.example # Template for credentials (safe to commit)
βββ agent_onboarding.md # Context for AI-based agent onboarding
βββ learner.csv # File where learnings are recorded
When writing test cases in natural language, configuration values can be referenced using angular brackets (< >).
Example:
Without config:
Search for ferries from Location-1 to Location-2
With config:
Search for ferries from <source> to <destination>
Here, <source> and <destination> are automatically picked from the corresponding configuration file.
-
Create an agent group folder:
src/main/agent_group/<group_name>/ -
Create a POR for the group:
src/main/por/por_<group_name>.pyRegister it in
por_master.py. -
Set up the agent structure:
agent_group/<group_name>/ βββ agent_details.py βββ tools/ βββ definitions/ β βββ agent_locator_tools.py β βββ agent_function_tools.py βββ implementation/ βββ android.py βββ ios.py βββ mweb.py βββ dweb.py
Use an AI-powered IDE (or any IDE with GitHub Copilot enabled):
- Add
agent_onboarding.mdas context - Tell the AI you want to onboard a new agent
- Answer the questions prompted by the AI
- Sit back and let the AI handle the onboarding process π
When onboarding a new tool, declare all tool definitions as abstract methods in the appropriate base class:
agent_locator_toolsβ Locator-related toolsagent_function_toolsβ Action or function-based tools
Use this pattern for elements or actions that do not require parameters.
@abstractmethod
def search_button(self):
"""
Search button to search all ferries available.
"""
passGuidelines:
- Method name should clearly represent the UI element or action
- Add a concise docstring explaining the purpose
- No parameters are required
Use this pattern when the tool requires runtime inputs.
@abstractmethod
def ferryTupleByFerryName(
self,
ferryName: Annotated[str, "Name of the ferry"],
ferryOccurence: Annotated[int, "Position among multiple ferries (Default: 1)"]
):
"""
Returns the ferry tuple based on ferry name or ferry operator name.
"""
passGuidelines:
- Use
Annotated[type, "description"]for parameters - Clearly describe each parameter
- Mention default values explicitly in descriptions
- Add a meaningful docstring
- Maximize Coverage with Minimal Locators
- Prefer flexible, descriptive selectors
- Reduce locator count and maintenance effort
- Tag Reference-Changing Locators to the Appropriate Agent Group If a locator interaction changes the page or context, tag it with the correct agent group reference.
run_configs.setRef("search_result_page")- Use Dynamic Parameters
- Substitute dynamic values as placeholders in locator strings
- Pass actual values at runtime
- Enable Self-Healing
- Always wrap locators with
selfHeal() - Enables recovery from minor UI text changes
def ferryTupleByBusName(
self,
ferryName: Annotated[str, "Name of the ferry operator"],
ferryOccurence: Annotated[int, "Position among multiple ferries (Default: 1)"]
):
run_configs.setRef("time_selection_page")
return agentic_base.helper.selfHeal(
"(//*[@data-autoid='inventoryList']"
"//*[contains(@class,'travelsName_') and text()='{ferryName}']"
"//ancestor::*[contains(@class,'tupleWrapper_')])[{ferryOccurence}]",
ferryName,
ferryOccurence
)Each agent represents a specific section or component of a page. Root locator(s) must be defined in the constructor.
Single Section Locator:
class search_widget:
def __init__(self):
run_configs.section_locator = ["//div[@data-section='abcd']"]Multiple Section Locators:
class search_widget:
def __init__(self):
run_configs.section_locator = [
"//div[@id='abcd']",
"//div[@data-component='xyz']"
]Location: core_agentic/agentic_base -> refChangeCheck()
Each agent_group must have a brief textual explanation describing what it represents on the UI.
Purpose:
- Accurate page/section change validation
- Helps the AI understand context transitions
- Ensures correct agents are supplied after navigation
- Git
- An IDE with Python support (AI-powered IDEs are optional but recommended)
- Python 3.13+
- An LLM API key (recommended: Gemini)
-
Clone the repository
git clone https://github.com/redbus-labs/LEAP cd LEAP -
Install dependencies
pip install -r requirements.txt
-
Install Playwright Browsers
playwright install
-
Set up credentials (choose one method):
Method 1: Environment Variables (Recommended) Guide - Link
Method 2: JSON File (Alternative)
cp credentials.json.example credentials.json # Edit credentials.json and add your API keysSecurity Note:
- The
credentials.jsonfile is already in.gitignoreand will not be committed to the repository credentials.json.exampleis a template file (safe to commit) that shows the expected structure- Environment variables are strongly recommended as they prevent accidental credential exposure in code, logs, or version control
- Never commit actual credentials to the repository
- The
-
Execute test_demo() under
core_agentic/test_trial.pypytest core_agentic/test_trial.py::test_demo -s
-
Description Quality Matters
The accuracy of execution is highly dependent on the quality and clarity of element and action descriptions. -
Supported LLMs
LEAP currently supports Gemini and AWS Bedrock models.
To add support for additional LLMs:- Onboard the model in
src/main/utilities/helper/helper_common.py - Implement it in the
setupLLM()method, following the existing Gemini or Bedrock integrations
- Onboard the model in
-
Recommended Models
LEAP works with any LLM, but for better accuracy in complex scenarios, we recommend:- Gemini 2.5 Pro
- Gemini 3 Pro
(Recommendations as of Jan 14, 2026)
-
Enable LLM Thinking
Keep the LLMβsthinkingenabled for improved reasoning and more reliable execution. -
Automation Support
- Browser automation is supported via Playwright
- Mobile app automation with Appium is a work in progress
You can experiment with app automation by implementing support inhelper_apps_implementation.py, using the existing Playwright browser implementation as a reference
We welcome contributions from the community! This project can only evolve with open source contributions.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please read our Contributing Guidelines before submitting contributions.
- Clone the repository
- Import into your IDE
- Run tests to ensure everything works
- Start coding!
Architected and Developed by: Krishna Hegde, Senior SDET, redBus
Guided and Mentored by: Chandrashekar Patil, Senior Director β QA, redBus
Special Thanks:
- Smruti Sourav Sahoo, SDET, redBus β for supporting the development efforts and being an early adopter of the project
- Vishnuvardhan Reddy Bhumannagari, Senior SDET Manager, redBus β for introducing AI-based visual assertions at redBus
- Rithish Saralaya, SVP Engineering, redBus β for organizing Project Nirman, an AI-first initiative that helped uncover key gaps in the framework and fast-track its growth.
Found a bug or need help? Please open an issue on GitHub.