Agent-skills lettuce-skill
install
source · Clone the upstream repo
git clone https://github.com/LambdaTest/agent-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/LambdaTest/agent-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/lettuce-skill" ~/.claude/skills/lambdatest-agent-skills-lettuce-skill && rm -rf "$T"
manifest:
lettuce-skill/SKILL.mdsource content
Lettuce BDD Skill (Legacy)
Note: Lettuce is largely unmaintained. For new Python BDD projects, use Behave instead.
Core Patterns
Feature File (features/login.feature)
Feature: User Login Scenario: Successful login Given I navigate to the login page When I enter "user@test.com" as email And I enter "password123" as password And I click login Then I should see the dashboard Scenario: Invalid login Given I navigate to the login page When I enter "bad@test.com" as email And I enter "wrong" as password And I click login Then I should see "Invalid credentials"
Step Definitions (features/steps.py)
from lettuce import step, world from selenium import webdriver from selenium.webdriver.common.by import By @step(r'I navigate to the login page') def navigate_to_login(step): world.browser = webdriver.Chrome() world.browser.get(world.base_url + '/login') @step(r'I enter "([^"]*)" as email') def enter_email(step, email): el = world.browser.find_element(By.ID, 'email') el.clear() el.send_keys(email) @step(r'I enter "([^"]*)" as password') def enter_password(step, password): el = world.browser.find_element(By.ID, 'password') el.clear() el.send_keys(password) @step(r'I click login') def click_login(step): world.browser.find_element(By.CSS_SELECTOR, 'button[type="submit"]').click() @step(r'I should see the dashboard') def see_dashboard(step): assert '/dashboard' in world.browser.current_url @step(r'I should see "([^"]*)"') def see_text(step, text): assert text in world.browser.page_source
Terrain (Setup/Teardown — terrain.py)
from lettuce import before, after, world @before.all def setup(): world.base_url = 'http://localhost:3000' @before.each_scenario def before_scenario(scenario): pass @after.each_scenario def cleanup(scenario): if hasattr(world, 'browser'): world.browser.quit() @after.all def teardown(total): print(f"Ran {total.scenarios_ran} scenarios")
Setup: pip install lettuce selenium
pip install lettuce seleniumRun: lettuce
or lettuce features/login.feature
lettucelettuce features/login.featureCloud Execution on TestMu AI
Set environment variables:
LT_USERNAME, LT_ACCESS_KEY
# terrain.py from selenium import webdriver import os @before.all def setup(): lt_options = { "user": os.environ["LT_USERNAME"], "accessKey": os.environ["LT_ACCESS_KEY"], "build": "Lettuce Build", "platformName": "Windows 11", "video": True, "console": True, } options = webdriver.ChromeOptions() options.set_capability("LT:Options", lt_options) world.browser = webdriver.Remote( command_executor=f"https://{os.environ['LT_USERNAME']}:{os.environ['LT_ACCESS_KEY']}@hub.lambdatest.com/wd/hub", options=options, )
Migration: Consider switching to behave
for active maintenance
behaveDeep Patterns
For advanced patterns, debugging guides, CI/CD integration, and best practices, see
reference/playbook.md.