Configuration Reference¶
This document provides comprehensive documentation for all configuration options available in the Optics Framework. The configuration system is managed by the ConfigHandler class and uses YAML files for configuration.
Overview¶
Configuration is project-specific: the one file that matters is config.yaml in your project directory. It is what optics execute <folder> / optics dry_run <folder> actually read, and built-in defaults fill in any field you omit.
Writing a project config
Run optics configure <folder> to answer a few questions and generate the file, or optics quickstart for the full guided setup (project + config + environment check via optics doctor).
Configuration Examples¶
Complete configuration for Android app testing with Appium:
# Core Settings
console: true
file_log: true
log_level: INFO
project_path: "./my_android_project"
halt_duration: 0.1
# Driver Configuration
driver_sources:
- appium:
enabled: true
url: "http://localhost:4723/wd/hub"
capabilities:
automationName: "UiAutomator2"
deviceName: "emulator-5554"
platformName: "Android"
platformVersion: "13.0"
appPackage: "com.example.app"
appActivity: "com.example.app.MainActivity"
# Element Sources
elements_sources:
- appium_find_element:
enabled: true
url: null
capabilities: {}
- appium_screenshot:
enabled: true
url: null
capabilities: {}
# Text Detection
text_detection:
- easyocr:
enabled: true
url: null
capabilities: {}
# Image Detection
image_detection:
- templatematch:
enabled: true
url: null
capabilities: {}
Configuration for web testing using Playwright:
# Core Settings
console: true
file_log: true
json_log: true
log_level: INFO
project_path: "./web_test_project"
halt_duration: 0.2
# Driver Configuration
driver_sources:
- playwright:
enabled: true
url: null
capabilities:
browser: "chromium"
headless: false
viewport:
width: 1920
height: 1080
# Element Sources
elements_sources:
- playwright_find_element:
enabled: true
url: null
capabilities: {}
- playwright_screenshot:
enabled: true
url: null
capabilities: {}
# Text Detection
text_detection:
- pytesseract:
enabled: true
url: null
capabilities: {}
# Image Detection
image_detection:
- templatematch:
enabled: true
url: null
capabilities: {}
Example with multiple drivers for fallback support:
driver_sources:
- appium:
enabled: true
url: "http://localhost:4723/wd/hub"
capabilities:
automationName: "UiAutomator2"
deviceName: "emulator-5554"
platformName: "Android"
- selenium:
enabled: true
url: "http://localhost:4444/wd/hub"
capabilities:
browserName: "chrome"
elements_sources:
- appium_find_element:
enabled: true
url: null
capabilities: {}
- selenium_find_element:
enabled: true
url: null
capabilities: {}
Quick Reference¶
| Category | Key Settings | Common Values |
|---|---|---|
| Logging | console, file_log, json_log, log_level | log_level: INFO or DEBUG |
| Paths | project_path, execution_output_path | ./my_project, ./outputs |
| Execution | halt_duration | 0.1 |
| Drivers | appium, selenium, playwright, ble | See Driver Sources tab |
| Element Sources | appium_find_element, playwright_screenshot, etc. | See Element Sources tab |
| Text Detection | easyocr, pytesseract, google_vision | See Text Detection tab |
| Image Detection | templatematch, remote_oir | See Image Detection tab |
| LLM Models | gemini | See LLM Models tab |
| AI Self-Healing | ai_self_heal | false (opt-in) |
Configuration Structure¶
All configurations are defined in YAML format. The main configuration file (config.yaml) supports the following top-level sections:
- Core settings - Logging, paths, execution parameters
- Driver sources - Automation frameworks (Appium, Selenium, Playwright, BLE)
- Element sources - Element detection methods
- Text detection engines - OCR capabilities
- Image detection engines - Template matching
- LLM models - Optional LLM backend for AI self-healing and
optics live's natural-language mode
Core Settings¶
console¶
Type: bool | Default: true
Enable or disable console log output.
file_log¶
Type: bool | Default: false
Enable writing logs to a file. When enabled, logs are written to the path specified by log_path or a default location.
file_log: true
log_path: "./logs/test_execution.log" # Optional, defaults to execution_output_path/logs.log
json_log¶
Type: bool | Default: false
Enable JSON format logging. When enabled, logs are written in JSON format to the path specified by json_path.
json_log: true
json_path: "./logs/test_logs.json" # Optional, defaults to execution_output_path/logs.json
log_level¶
Type: str | Default: "INFO"
Sets the verbosity of log messages. Valid values (in order of verbosity):
DEBUG- Detailed information for troubleshootingINFO- General informational messages (default)WARNING- Warning messages onlyERROR- Error messages onlyCRITICAL- Critical failures only
log_path¶
Type: Optional[str] | Default: null
Path for log file. If not specified and file_log is enabled, defaults to {execution_output_path}/logs.log.
json_path¶
Type: Optional[str] | Default: null
Path for JSON log file. If not specified and json_log is enabled, defaults to {execution_output_path}/logs.json.
project_path¶
Type: Optional[str] | Default: null
Root directory for test project files. This folder holds your test cases, modules, and elements (either the sample subdir layout — test_cases/, modules/, test_data/ — or flat CSVs; the runner discovers them by content) plus any input_templates/ images.
execution_output_path¶
Type: Optional[str] | Default: null (auto-generated)
Directory where execution outputs (logs, screenshots, etc.) are stored. If not specified, defaults to {project_path}/execution_output when project_path is set, or {cwd}/execution_output (current working directory) otherwise.
halt_duration¶
Type: float | Default: 0.1
Pause duration (in seconds) between actions. This helps ensure UI stability and prevents race conditions.
include¶
Type: Optional[List[str]] | Default: null
List of test case names to include in execution. Only the specified test cases will be executed; all others will be skipped.
exclude¶
Type: Optional[List[str]] | Default: null
List of test case names to exclude from execution. All other test cases will be executed.
event_attributes_json¶
Type: Optional[str] | Default: null
Path to a JSON file containing event attributes for the Event SDK. This file defines custom attributes to be included in event tracking.
ai_self_heal¶
Type: bool | Default: false
Last-resort recovery for element location. When every locator strategy (XPath, text, OCR, image) fails for a self-healing-capable keyword (e.g. Press Element, Enter Text), a bounded LLM-driven loop reads the screen and attempts to recover before the keyword fails outright.
Opt-in and inert unless an entry under llm_models is also enabled — a missing or misconfigured LLM degrades this to a no-op rather than a failure:
See LLM Models below for backend configuration.
Driver Sources¶
Driver sources define the automation frameworks used to control devices or browsers.
Purpose: Mobile app automation for Android and iOS devices.
Configuration:
driver_sources:
- appium:
enabled: true
url: "http://localhost:4723/wd/hub"
capabilities:
automationName: "UiAutomator2" # or "XCUITest" for iOS
deviceName: "emulator-5554"
platformName: "Android" # or "iOS"
platformVersion: "13.0"
appPackage: "com.example.app"
appActivity: "com.example.app.MainActivity"
udid: "device_unique_id" # Optional, for specific device
Common Capabilities:
| Capability | Android | iOS | Description |
|---|---|---|---|
automationName | "UiAutomator2" | "XCUITest" | Automation framework |
platformName | "Android" | "iOS" | Platform identifier |
platformVersion | "13.0" | "16.0" | OS version |
deviceName | Device identifier | Device identifier | Device name |
appPackage | Package name | - | Android app package |
appActivity | Activity name | - | Android activity |
udid | Device UDID | Device UDID | Unique device ID |
Android: elements off-screen may be missing from Capture Pagesource
On Android (UiAutomator2), elements not currently rendered on screen (e.g. scrolled out of view) are omitted entirely from Capture Pagesource and the page source-backed element sources by default -- so Assert Visibility can't distinguish "off-screen" from "doesn't exist" for them, since they never show up in the tree at all. Set allowInvisibleElements: true under appium:settings to include them:
iOS (XCUITest) includes such elements by default (with a visible="false" attribute) -- no equivalent setting needed.
Purpose: Web browser automation.
Configuration:
driver_sources:
- selenium:
enabled: true
url: "http://localhost:4444/wd/hub" # Selenium Grid or standalone
capabilities:
browserName: "chrome" # or "firefox", "safari", "edge"
browserVersion: "latest"
platformName: "Windows"
Common Capabilities:
| Capability | Values | Description |
|---|---|---|
browserName | "chrome", "firefox", "safari", "edge" | Browser type |
browserVersion | Version string | Browser version |
platformName | "Windows", "Linux", "macOS" | Operating system |
Purpose: Modern web automation with better reliability and performance.
Configuration:
driver_sources:
- playwright:
enabled: true
url: null # Playwright runs locally
capabilities:
browser: "chromium" # or "firefox", "webkit"
headless: false
viewport:
width: 1920
height: 1080
Common Capabilities:
| Capability | Values | Description |
|---|---|---|
browser | "chromium", "firefox", "webkit" | Browser engine |
headless | true, false | Run browser in headless mode |
viewport | {width, height} | Browser viewport dimensions |
Purpose: Bluetooth Low Energy (BLE) device automation for non-intrusive mouse/keyboard control.
Configuration:
driver_sources:
- ble:
enabled: true
url: null
capabilities:
device_id: "Samsung A50"
port: "/dev/ttyACM0"
x_invert: 1
y_invert: 1
pixel_width: 1080
pixel_height: 2336
mickeys_height: 2336
mickeys_width: 1080
Common Capabilities:
| Capability | Description |
|---|---|
device_id | Device identifier |
port | Serial port for BLE communication |
x_invert, y_invert | Coordinate inversion flags |
pixel_width, pixel_height | Screen pixel dimensions |
mickeys_width, mickeys_height | Mouse coordinate dimensions |
Purpose: Smart TV automation via platform-specific Appium profiles. Android TV is supported via the Android profile (same as phones). LG webOS and Samsung Tizen need separate setup, described below.
| Platform | Notes |
|---|---|
| Android TV | Supported via Android profile — same as phone automation |
| Samsung Tizen | D-pad navigation + DOM access (limited) |
| LG webOS | D-pad navigation only (blind remote control) |
Both Tizen and webOS use D-pad buttons (UP/DOWN/ENTER/BACK) for navigation, not touch. Touch-based methods (click_element, swipe, enter_text) raise an error on TVs.
Samsung Tizen prerequisites: - Tizen Studio installed; TIZEN_HOME set - TV in Developer Mode (Settings → enter 12345 via 123 button → Client IP = your Appium host) - sdb connect <tv-ip> and verified with sdb devices - Appium 2.x with driver: appium driver install --source=npm appium-tizen-tv-driver - RC token: appium driver run tizentv pair-remote --host <tv-ip> (approve on-screen prompt) - Debug-signed .wgt app binary - Matching chromedriver version for the TV's Chromium
driver_sources:
- appium:
enabled: true
url: "http://localhost:4723"
capabilities:
platformName: TizenTV
appium:automationName: TizenTV
appium:deviceAddress: 192.168.1.50
appium:rcToken: "14184553"
appium:appPackage: com.example.app
appium:app: /path/to/app.wgt
appium:chromedriverExecutableDir: /path/to/chromedrivers
elements_sources:
- appium_page_source:
enabled: true
- appium_screenshot:
enabled: true
LG webOS prerequisites: - webOS SDK installed (ares-cli on PATH) - TV in Developer Mode (Dev Mode app → signed in → ON; expires every ~50 hours) - ares-setup-device -n <name> -i <ip> to register the TV - Appium 2.x with driver: appium driver install --source=npm appium-lg-webos-driver - RC pairing happens automatically on first session (approve on-screen) - Matching chromedriver version
driver_sources:
- appium:
enabled: true
url: "http://localhost:4723"
capabilities:
platformName: LGTV
appium:automationName: webOS
appium:deviceHost: 192.168.1.50
appium:appId: com.example.app
appium:rcMode: rc
appium:useSecureWebsocket: true
appium:newCommandTimeout: 600
elements_sources:
- appium_screenshot:
enabled: true
Limitations:
- Methods that raise an error on TVs — Touch:
click_element,press_element,press_coordinates,tap_at_coordinates,swipe*; Keyboard:enter_text,clear_text; Other:scroll,get_text_element,press_xpath_using_coordinates. - Methods that work everywhere:
launch_app,press_keycode,execute_script,terminate. - Text input isn't supported — use a sequence of
Press Keycodesteps for D-pad navigation through on-screen keyboards. - Native screenshots can hang on Tizen; Optics renders the DOM to canvas instead. DRM/video content appears black — judge playback from UI elements.
- Chromedriver version must match the TV's Chromium exactly (e.g. webOS 6 → Chromium 79 → chromedriver 79.x). Mismatches cause "cannot connect to chrome" errors.
- webOS and Tizen drivers require Appium 2.x (no Appium 3 support yet).
References: - LG webOS developer site - Samsung Developer — Tizen TV - Appium webOS driver - Appium Tizen driver
Element Sources¶
Element sources define methods for locating and capturing UI elements.
appium_find_element¶
Purpose: Locates elements using Appium's native element finding strategies (XPath, ID, etc.).
appium_page_source¶
Purpose: Retrieves the entire XML page source from Appium for element location.
appium_screenshot¶
Purpose: Captures screenshots through Appium for visual element detection.
selenium_find_element¶
Purpose: Locates elements using Selenium's element finding strategies (CSS selectors, XPath, etc.).
selenium_screenshot¶
Purpose: Captures screenshots from Selenium browser sessions.
playwright_find_element¶
Purpose: Locates elements using Playwright's modern locator API (CSS, text, XPath).
playwright_page_source¶
Purpose: Retrieves DOM HTML from Playwright for element location.
playwright_screenshot¶
Purpose: Captures high-quality screenshots from Playwright sessions.
camera_screenshot¶
Purpose: Captures screenshots from external cameras or capture cards (useful for production monitoring).
Text Detection¶
Text detection engines provide OCR (Optical Character Recognition) capabilities for locating text on screen.
Purpose: EasyOCR library for text recognition. Provides good accuracy but may be slower.
Performance
EasyOCR provides excellent accuracy but can be slower than Pytesseract. Consider using it when accuracy is more important than speed.
Purpose: Tesseract OCR engine via Python wrapper. Generally faster than EasyOCR.
Speed vs Accuracy
Pytesseract is generally faster than EasyOCR but may have lower accuracy for complex text or non-standard fonts.
Purpose: Google Cloud Vision API for text recognition. Requires API credentials.
text_detection:
- google_vision:
enabled: true
url: null
capabilities:
credentials_path: "./config/google_credentials.json"
API Credentials Required
You must provide valid Google Cloud credentials in the credentials_path capability.
Image Detection¶
Image detection engines provide template matching capabilities for locating UI elements by image.
Purpose: OpenCV-based template matching for image recognition.
Local Processing
Template matching runs locally using OpenCV and does not require external services.
Matching is two-stage: a cv2.matchTemplate fast path handles exact same-scale matches, and a SIFT + FLANN + RANSAC fallback covers scaled or rotated instances. capabilities.sift_nfeatures (default 2000) caps the SIFT features extracted per frame in that fallback, bounding per-call memory; raise it only if scaled matches fail on feature-poor screens.
LLM Models¶
LLM backends power two opt-in features: the ai_self_heal recovery path above, and optics live's natural-language mode (Ctrl-N). Both stay inert until an entry below is enabled — the backend SDK is only imported when its engine is enabled, so leaving this section out has no cost for projects that don't use either feature.
Purpose: Google Gemini via the google-genai SDK, supporting both the Gemini Developer API and Vertex AI. Requires the optional llm extra: pip install 'optics-framework[llm]'.
llm_models:
- gemini:
enabled: true
capabilities:
model: gemini-3.8-flash # optional; framework default is gemini-2.5-flash
temperature: 0.0 # optional; this is the default
# use_vertexai: true # optional; else uses GOOGLE_GENAI_USE_VERTEXAI
# project: your-project # optional Vertex override; else GOOGLE_CLOUD_PROJECT
# location: us-east4 # optional Vertex override; else GOOGLE_CLOUD_LOCATION
With no capabilities set, the SDK auto-detects everything from environment variables:
| Variable | Purpose |
|---|---|
GEMINI_API_KEY / GOOGLE_API_KEY | Gemini Developer API key |
GOOGLE_GENAI_USE_VERTEXAI | Switch to Vertex AI |
GOOGLE_CLOUD_PROJECT | Vertex AI project |
GOOGLE_CLOUD_LOCATION | Vertex AI location |
GOOGLE_APPLICATION_CREDENTIALS | Vertex AI service account credentials |
Don't hardcode credentials
capabilities.api_key / capabilities.gemini_api_key are also accepted but log a warning when used — prefer the environment variables above so keys never end up in a committed config.yaml.
Dependency Configuration Structure¶
All dependency types (driver sources, element sources, text detection, image detection) use the same DependencyConfig structure:
enabled¶
Type: bool | Required: true
Whether this dependency is enabled. Only enabled dependencies are used by the framework.
url¶
Type: Optional[str] | Default: null
Service URL for remote dependencies (e.g., Appium server, remote OCR service). Set to null for local dependencies.
capabilities¶
Type: Dict[str, Any] | Default: {}
Dependency-specific configuration options. The structure varies by dependency type.
Example Dependency Configuration¶
driver_sources:
- appium:
enabled: true
url: "http://localhost:4723/wd/hub"
capabilities:
automationName: "UiAutomator2"
deviceName: "emulator-5554"
platformName: "Android"
How configuration is loaded¶
When you run optics execute or optics dry_run, the framework reads the target folder's own config.yaml. Any field you leave out falls back to the built-in defaults (for example, every source defaults to enabled: false). A project's config.yaml is the single source of truth for that run — there is no global config layer to merge.
Best Practices¶
- Enable Only What You Need: Disabled dependencies reduce overhead and improve performance
- Use Appropriate OCR: Choose EasyOCR for accuracy, Pytesseract for speed
- Set Log Level Appropriately: Use DEBUG during development, INFO or WARNING in production
- Configure Execution Paths: Set
project_pathandexecution_output_pathfor organized output - Keep Each Project's
config.yamlSelf-Contained: It is the only config the runner reads - Test Configuration Changes: Verify configurations work correctly before running large test suites