autonomo-angular
v1.0.0
Published
Angular service and directives for Autonomo integration
Readme
autonomo-angular
⚠️ Testing Only - This package is not yet published to npm. It is included for testing and development purposes only.
Angular integration for Autonomo - AI-powered application testing.
Installation
For local development/testing, link the package from this monorepo:
# From the autonomo repo root
cd packages/autonomo-angular
npm link
# In your Angular project
npm link autonomo-angularQuick Start
1. Configure the module
Using NgModule:
import { AutonomoModule } from 'autonomo-angular';
@NgModule({
imports: [
AutonomoModule.forRoot({
name: 'my-app',
serverUrl: 'ws://localhost:9876',
debug: true, // optional
}),
],
})
export class AppModule {}Using Standalone Components:
import { AutonomoService, AUTONOMO_DIRECTIVES } from 'autonomo-angular';
@Component({
standalone: true,
imports: [...AUTONOMO_DIRECTIVES],
providers: [AutonomoService],
})
export class AppComponent {
private autonomo = inject(AutonomoService);
ngOnInit() {
this.autonomo.init({
name: 'my-app',
serverUrl: 'ws://localhost:9876',
});
}
}2. Mark interactive elements
Use directives to register elements:
<div autonomoScreen="login-page">
<input
autonomoFill="email-input"
[(ngModel)]="email"
autonomoHint="Enter your email address"
/>
<input
autonomoFill="password-input"
[(ngModel)]="password"
type="password"
/>
<input
type="checkbox"
autonomoToggle="remember-me"
[(ngModel)]="rememberMe"
/>
<button
autonomoTap="submit-btn"
[autonomoTapHandler]="onSubmit"
>
Login
</button>
</div>3. Set screen and user context
import { AutonomoService } from 'autonomo-angular';
@Component({ ... })
export class DashboardComponent {
private autonomo = inject(AutonomoService);
ngOnInit() {
// Track current screen
this.autonomo.setScreen('dashboard');
// Track user context
this.autonomo.setUser({
id: this.user.id,
email: this.user.email,
role: this.user.role,
});
// Track additional app data
this.autonomo.mergeData({
cartItems: this.cart.length,
notifications: this.notifications.unread,
});
}
}4. Configure MCP
Add to .vscode/mcp.json:
{
"servers": {
"autonomo": {
"command": "autonomo-mcp",
"env": {
"AUTONOMO_PORT": "9876"
}
}
}
}Directives
autonomoTap
Registers a tappable/clickable element:
<button
autonomoTap="action-button"
[autonomoTapHandler]="handleClick"
[autonomoDisabled]="isLoading"
autonomoHint="Triggers the main action"
>
Click Me
</button>autonomoFill
Registers a fillable input:
<input
autonomoFill="search-input"
[(ngModel)]="searchTerm"
[autonomoOnSubmit]="onSearch"
autonomoHint="Search for products"
/>autonomoToggle
Registers a toggle (checkbox, switch, radio):
<input
type="checkbox"
autonomoToggle="dark-mode"
[(ngModel)]="darkMode"
/>autonomoScreen
Sets the current screen/page name:
<div autonomoScreen="settings-page">
<!-- page content -->
</div>Custom Actions
For complex flows that can't be expressed as single element interactions:
import { useCustomAction } from 'autonomo-angular';
@Component({ ... })
export class OtpComponent {
constructor() {
useCustomAction('enterOTP', async (value) => {
if (!value || value.length !== 6) {
return { success: false, error: 'OTP must be 6 digits' };
}
// Fill all OTP boxes
this.otpDigits = value.split('');
return { success: true, message: 'OTP entered' };
});
}
}Service API
AutonomoService
class AutonomoService {
// Observables (for RxJS)
connected$: Observable<boolean>;
bridgeId$: Observable<string | null>;
// Signals (for Angular 16+)
connected: Signal<boolean>;
bridgeId: Signal<string | null>;
// Methods
init(config: AutonomoConfig): void;
setScreen(screen: string): void;
setUser(user: { id?: string; email?: string; role?: string }): void;
mergeData(data: Record<string, unknown>): void;
reportState(): void;
}Development vs Production
Only enable Autonomo in development:
import { environment } from './environments/environment';
@NgModule({
imports: [
...(environment.production ? [] : [
AutonomoModule.forRoot({
name: 'my-app',
}),
]),
],
})
export class AppModule {}Or with standalone:
@Component({ ... })
export class AppComponent {
private autonomo = inject(AutonomoService, { optional: true });
ngOnInit() {
if (!environment.production) {
this.autonomo?.init({ name: 'my-app' });
}
}
}Troubleshooting
Elements not appearing
Ensure directives are imported:
// NgModule
@NgModule({
imports: [AutonomoModule],
})
// Standalone
@Component({
imports: [...AUTONOMO_DIRECTIVES],
})Connection issues
Check the WebSocket server is running:
this.autonomo.connected$.subscribe(connected => {
console.log('Autonomo connected:', connected);
});Debug mode
Enable debug logging:
AutonomoModule.forRoot({
name: 'my-app',
debug: true,
})