stepwise-flow
v0.1.0
Published
A site-agnostic browser automation framework with plugin support
Maintainers
Readme
Stepwise
A site-agnostic browser automation framework with plugin support. Built on Playwright.
Features
- Flow-based automation: Define multi-step browser automation flows declaratively
- Plugin system: Extend functionality with custom plugins for site-specific behaviors
- Variable store: Share data between steps using
${path.to.value}syntax - Built-in step types: click, type, wait, extract, screenshot, navigate, and more
- Conditional logic: If/else branching and polling with conditions
- TypeScript-first: Full type safety with discriminated unions
Installation
npm install stepwise playwrightQuick Start
import { FlowEngine, PluginRegistry, registerBuiltinPlugins } from 'stepwise';
// Register built-in plugins
registerBuiltinPlugins();
// Create a flow engine
const engine = new FlowEngine({
headless: false,
timeout: 30000,
});
// Define a flow
const flow = {
name: 'Example Search',
description: 'Search Wikipedia',
inputs: {
searchTerm: { type: 'string' as const, description: 'Search term', required: true },
},
steps: [
{ type: 'navigate' as const, url: 'https://www.wikipedia.org' },
{ type: 'type' as const, selector: '#searchInput', text: '${inputs.searchTerm}' },
{ type: 'click' as const, selector: 'button[type="submit"]' },
{ type: 'wait' as const, selector: '#firstHeading' },
{
type: 'extract' as const,
selector: '#firstHeading',
attribute: 'textContent',
variable: 'pageTitle',
},
{ type: 'log' as const, message: 'Found: ${pageTitle}' },
],
};
// Run the flow
const result = await engine.run(flow, { searchTerm: 'TypeScript' });
console.log(result);Step Types
Basic Steps
- navigate: Go to a URL
- click: Click an element
- type: Type text into an element
- wait: Wait for an element to appear
Data Steps
- extract: Extract data from elements
- log: Log messages to console
Control Flow
- if: Conditional branching
- pollUntil: Poll until a condition is met
Plugin Steps
- plugin: Execute a registered plugin
Plugin System
Create custom plugins by extending BasePlugin:
import { BasePlugin, PluginContext, StepResult } from 'stepwise';
interface MyPluginParams {
myParam: string;
}
class MyPlugin extends BasePlugin<MyPluginParams> {
readonly metadata = {
namespace: 'myapp',
name: 'myPlugin',
description: 'Does something useful',
version: '1.0.0',
};
protected async doExecute(
params: MyPluginParams,
context: PluginContext
): Promise<StepResult> {
const { page } = context;
// Your automation logic here
return { success: true };
}
}Register and use:
import { PluginRegistry } from 'stepwise';
const registry = PluginRegistry.getInstance();
registry.register(new MyPlugin());
// In a flow:
{
type: 'plugin',
pluginId: 'myapp:myPlugin',
params: { myParam: 'value' },
}Variable Store
Variables can be set and referenced using ${path.to.value} syntax:
// Set in extract step
{ type: 'extract', selector: '.price', variable: 'product.price' }
// Reference in other steps
{ type: 'log', message: 'Price: ${product.price}' }
{ type: 'type', selector: '#input', text: '${product.price}' }Flow inputs are available under ${inputs.fieldName}.
Local Development
- Build the package:
cd stepwise
npm install
npm run build- In a downstream project (e.g.
tcdd-bilet) add a dependency to the local folder:
cd tcdd-bilet
npm install ../stepwiseOr use npm link for development.
API Reference
FlowEngine
Main execution engine for running flows.
const engine = new FlowEngine(options);
const result = await engine.run(flow, inputs);
await engine.close();PluginRegistry
Singleton registry for managing plugins.
const registry = PluginRegistry.getInstance();
registry.register(plugin);
registry.registerLazy('namespace', 'name', async () => new Plugin());
const plugin = await registry.get('namespace:name');BrowserManager
Singleton for browser lifecycle management.
const browser = BrowserManager.getInstance();
await browser.init({ headless: false });
const page = await browser.getPage();
await browser.close();License
MIT
