API Reference
Complete reference for Loopi's automation step types and executor API
API & Executor Reference
This page documents Loopi's automation step types and the main executor API.
Key Entry Points
AutomationExecutor
The main executor class handles step execution and variable management.
Methods:
executeStep(browserWindow, step)– Execute a single automation stepevaluateConditional(browserWindow, config)– Evaluate conditional logicsubstituteVariables(input)– Replace{{varName}}with runtime valuesinitVariables(vars)– Initialize runtime variablesgetVariables()– Get current variable state
Variable Substitution
All step values support variable substitution using {{varName}} syntax with full support for:
Simple Variables
// Variables: { productId: "123", userId: "user456" }
const url = "{{productId}}";
// Result: "123"Nested Object Properties
// Variables: { user: { name: "John", email: "john@example.com" } }
const email = "{{user.email}}";
// Result: "john@example.com"Array Element Access
// Variables: { users: [{id: 1, name: "John"}, {id: 2, name: "Jane"}] }
const firstName = "{{users[0].name}}";
// Result: "John"Mixed & Deep Nesting
// Complex nested structures
const value = "{{response.data[0].user.profile.email}}";
const matrix = "{{grid[0][1]}}";Regex Pattern
Variables are matched with: /\{\{\s*([a-zA-Z0-9_\[\].]+)\s*\}\}/g
This supports:
- Simple names:
{{varName}} - Nested properties:
{{obj.prop}} - Array indices:
{{array[0]}} - Mixed access:
{{array[0].prop[1].name}}
Unknown variables resolve to empty string.
Additional context: See Variable System for complete guide.
Supported Step Types
All steps extend the base StepBase interface:
interface StepBase {
id: string;
description: string;
type: string;
}Navigate
Load a URL in the browser.
interface StepNavigate extends StepBase {
type: "navigate";
value: string; // URL (supports {{var}})
}Example:
{
"id": "1",
"type": "navigate",
"description": "Go to product page",
"value": "https://example.com/product/{{productId}}"
}Click
Click an element on the page.
interface StepClick extends StepBase {
type: "click";
selector: string; // CSS selector
}Example:
{
"id": "2",
"type": "click",
"description": "Click add to cart",
"selector": ".add-to-cart-button"
}Type
Enter text into an input field.
interface StepType extends StepBase {
type: "type";
selector: string; // CSS selector for input
value: string; // Text to type (supports {{var}})
credentialId?: string; // Optional credential reference
}Example:
{
"id": "3",
"type": "type",
"description": "Enter email",
"selector": "input[name='email']",
"value": "{{userEmail}}"
}Wait
Pause execution for a specified duration.
interface StepWait extends StepBase {
type: "wait";
value: string; // Duration in seconds
}Example:
{
"id": "4",
"type": "wait",
"description": "Wait for page load",
"value": "2"
}Screenshot
Capture a screenshot of the current page.
interface StepScreenshot extends StepBase {
type: "screenshot";
savePath?: string; // Optional file path
}Returns: Base64-encoded PNG image
Example:
{
"id": "5",
"type": "screenshot",
"description": "Capture checkout page",
"savePath": "checkout.png"
}Extract
Extract text from an element.
interface StepExtract extends StepBase {
type: "extract";
selector: string; // CSS selector
storeKey?: string; // Variable name to store result
}Example:
{
"id": "6",
"type": "extract",
"description": "Get product price",
"selector": ".product-price",
"storeKey": "price"
}Extract with Logic
Extract and evaluate a condition.
interface StepExtractWithLogic extends StepBase {
type: "extractWithLogic";
selector: string;
condition: "equals" | "contains" | "greaterThan" | "lessThan";
expectedValue: string;
transformType?: "stripCurrency" | "stripNonNumeric" | "removeChars" | "regexReplace";
parseAsNumber?: boolean;
}Returns: { value: string; conditionMet: boolean }
Example:
{
"id": "7",
"type": "extractWithLogic",
"description": "Check if price > $50",
"selector": ".price",
"condition": "greaterThan",
"expectedValue": "50",
"transformType": "stripCurrency",
"parseAsNumber": true
}API Call
Make HTTP requests.
interface StepApiCall extends StepBase {
type: "apiCall";
method?: "GET" | "POST" | "PUT" | "DELETE";
url: string; // Supports {{var}}
headers?: Record<string, string>;
body?: string; // JSON string, supports {{var}}
storeKey?: string; // Variable to store response
}Example:
{
"id": "8",
"type": "apiCall",
"description": "Fetch product details",
"method": "GET",
"url": "https://api.example.com/products/{{productId}}",
"headers": {
"Authorization": "Bearer {{apiToken}}"
},
"storeKey": "productData"
}Scroll
Scroll to an element or by a specific amount.
interface StepScroll extends StepBase {
type: "scroll";
scrollType: "toElement" | "byAmount";
selector?: string; // For toElement
scrollAmount?: number; // Pixels for byAmount
}Example:
{
"id": "9",
"type": "scroll",
"description": "Scroll to footer",
"scrollType": "toElement",
"selector": "footer"
}Select Option
Select an option from a dropdown.
interface StepSelectOption extends StepBase {
type: "selectOption";
selector: string; // <select> element
optionValue?: string; // Value attribute
optionIndex?: number; // 0-based index
}Example:
{
"id": "10",
"type": "selectOption",
"description": "Select country",
"selector": "select[name='country']",
"optionValue": "US"
}File Upload
Upload a file to an input.
interface StepFileUpload extends StepBase {
type: "fileUpload";
selector: string; // <input type="file">
filePath: string; // Absolute path to file
}Note: File upload has browser limitations and may not work in all scenarios.
Example:
{
"id": "11",
"type": "fileUpload",
"description": "Upload avatar",
"selector": "input[type='file']",
"filePath": "/path/to/avatar.jpg"
}Hover
Trigger mouseover event on an element.
interface StepHover extends StepBase {
type: "hover";
selector: string;
}Example:
{
"id": "12",
"type": "hover",
"description": "Show dropdown menu",
"selector": ".menu-trigger"
}Set Variable
Create or update a variable with automatic type detection.
interface StepSetVariable extends StepBase {
type: "setVariable";
variableName: string;
value: string; // Auto-typed based on content
}Auto-Type Detection:
"42"→number: 42"true"→boolean: true'{"key":"value"}'→object: {key: "value"}'[1,2,3]'→array: [1,2,3]- Other text →
string
Example:
{
"id": "13",
"type": "setVariable",
"description": "Set user ID",
"variableName": "userId",
"value": "12345"
}Result: Variable userId stored as number: 12345 (not string!)
Type-aware examples:
{
"type": "setVariable",
"variableName": "threshold",
"value": "100"
}
// Stored as number: 100
// Now you can use in comparisons: {{threshold}} > 50{
"type": "setVariable",
"variableName": "userData",
"value": "{\"name\": \"John\", \"age\": 30}"
}
// Stored as object with direct property access
// Use: {{userData.name}}, {{userData.age}}Modify Variable
Perform operations on existing variables with type safety.
interface StepModifyVariable extends StepBase {
type: "modifyVariable";
variableName: string;
operation: "set" | "increment" | "decrement" | "append";
value?: string;
}Operations:
set– Assign new value (auto-typed)increment– Add to numeric variable (maintains number type)decrement– Subtract from numeric variable (maintains number type)append– Concatenate to string variable
Type-safe operations:
{
"id": "14",
"type": "modifyVariable",
"variableName": "counter",
"operation": "increment"
}✅ Works if counter is number
❌ Fails if counter is string
Example - Increment:
{
"type": "modifyVariable",
"variableName": "visitCount",
"operation": "increment"
}
// If visitCount was 10, now 11 (still a number)Example - Set with auto-type:
{
"type": "modifyVariable",
"variableName": "status",
"operation": "set",
"value": "completed"
}
// Stored as string: "completed"Example - Append:
{
"type": "modifyVariable",
"variableName": "log",
"operation": "append",
"value": " - step completed"
}
// Original: "Started", Result: "Started - step completed"Conditional Evaluation
The evaluateConditional method supports:
Condition Types
elementExists– Check if selector matches any elementvalueMatches– Extract and compare value
Comparison Operations
equals– Exact matchcontains– Substring matchgreaterThan– Numeric (requires parseAsNumber)lessThan– Numeric (requires parseAsNumber)
Transforms
Apply before comparison:
stripCurrency– Remove $, €, £, ¥stripNonNumeric– Keep only digits and decimalremoveChars– Remove specific charactersregexReplace– Advanced text replacement
Example Configuration
{
conditionType: "valueMatches",
selector: ".price",
comparison: "greaterThan",
expectedValue: "100",
transformType: "stripCurrency",
parseAsNumber: true
}Returns:
{
conditionResult: boolean;
effectiveSelector?: string | null;
}IPC Channels
Communication between renderer and main process.
browser:open
- Purpose: Open browser window
- Parameters:
(url?: string) - Returns:
void
browser:close
- Purpose: Close browser window
- Parameters:
none - Returns:
void
browser:runStep
- Purpose: Execute a step
- Parameters:
(step: AutomationStep) - Returns:
Promise<any>(step result)
executor:initVariables
- Purpose: Initialize variables
- Parameters:
(vars?: Record<string, string>) - Returns:
true
executor:getVariables
- Purpose: Get current variables
- Parameters:
none - Returns:
Record<string, string>
browser:runConditional
- Purpose: Evaluate condition
- Parameters:
(config: ConditionalConfig) - Returns:
{ conditionResult: boolean; effectiveSelector?: string }
pick-selector
- Purpose: Launch element picker
- Parameters:
(url: string) - Returns:
Promise<string | null>(CSS selector)
Usage Examples
Basic Flow
// 1. Initialize variables
await ipcRenderer.invoke('executor:initVariables', {
baseUrl: 'https://shop.com',
productId: '123'
});
// 2. Navigate
await ipcRenderer.invoke('browser:runStep', {
id: '1',
type: 'navigate',
description: 'Go to product',
value: '{{baseUrl}}/product/{{productId}}'
});
// 3. Extract price
const price = await ipcRenderer.invoke('browser:runStep', {
id: '2',
type: 'extract',
description: 'Get price',
selector: '.price',
storeKey: 'productPrice'
});
// 4. Get variables
const vars = await ipcRenderer.invoke('executor:getVariables');
console.log(vars.productPrice); // "$29.99"Conditional Logic
const result = await ipcRenderer.invoke('browser:runConditional', {
conditionType: 'valueMatches',
selector: '.stock-status',
comparison: 'contains',
expectedValue: 'In Stock'
});
if (result.conditionResult) {
// Item in stock, proceed with purchase
await ipcRenderer.invoke('browser:runStep', {
type: 'click',
selector: '.add-to-cart'
});
}Next Steps
- See Detailed API for complete TypeScript definitions
- Check Examples for real-world usage
- Read Developer Guide to extend Loopi