Universal Automation Protocol (UAP)

Info

UAP hace que la automatización sea accesible, portable y preparada para el futuro en distintas plataformas.

Universal Automation Protocol (UAP) es un estándar abierto creado por HuBrowser para definir y ejecutar tareas de automatización en cualquier dispositivo o plataforma. Tanto si empiezas como si ya tienes experiencia, UAP te permite grabar, importar y exportar automatizaciones en un formato simple y legible. Ejecuta tus automatizaciones con cualquier app compatible con UAP, sin depender de un único proveedor.

Tip

Si no tienes conocimientos técnicos, aun así puedes leer esta página y entender fácilmente cómo escribir tus propios pasos de automatización. Si tienes perfil técnico, aquí verás cómo encaja esto con testing UI empresarial y automatización multiplataforma.

  • Fácil para personas: usa JSON, así que es sencillo de leer y escribir.
  • Seguro a nivel de tipos: los tipos del protocolo están definidos en TypeScript para mayor fiabilidad.
  • AI-first: está diseñado para la nueva era de agentes de IA en móvil y resuelve problemas que estándares heredados como Playwright o Selenium no pueden cubrir bien.
  • Multiplataforma: permite compartir scripts de automatización entre plataformas. Aunque HuBrowser no soporte iPhone, tus scripts pueden seguir funcionando.

Términos

  • Mode: los 3 modos que soportamos:
    • instruction: instrucción en lenguaje natural para la acción.
    • recording: pasos de automatización grabados.
    • script: pasos de automatización escritos como script.
  • Harden: cambia de un modo flexible a uno más determinista, por ejemplo de instruction a script, haciendo la automatización más rápida y precisa.
  • Soften: cambia de un modo determinista a uno más flexible, por ejemplo de script a instruction, haciendo la automatización más adaptable, aunque potencialmente más lenta.

Ejemplo: acción UAP (JSON)

[
	{
		"command": "goal",
		"goal": "Submit the form"
	},
	{
		"command": "tap",
		"selector": "#submit-button",
		"displayMsg": "Tap the submit button"
	},
	{
		"command": "wait",
		"duration": 2000,
		"displayMsg": "Wait for 2 seconds"
	},
	{
		"command": "assert",
		"assertion": {
			"type": "visible",
			"selector": "#success-message"
		},
		"displayMsg": "Check if success message is visible"
	}
]

Este ejemplo muestra un flujo sencillo de envío de formulario. Las acciones UAP son fáciles de escribir y de entender.

Configuración de automatización (TypeScript)

/**
 * Types for AI actions (specs only)
 * Adapt best practices from Playwright and Puppeteer for AI era
 */

// Common base for all AI actions
export interface CommonAIAction {
	/**
	 * The command to execute (e.g. 'tap', 'wait', 'open_link', etc)
	 */
	command: string
	/**
	 * Optional message to display to the user
	 */
	displayMsg?: string
	/**
	 * If true, do not wait for this action to finish before proceeding to the next task (AI era best practice)
	 * Defaults to false
	 */
	noWait?: boolean
	/**
	 * Wait strategy
	 */
	waitUntil?:
		| 'domcontentloaded'
		| 'load'
		| 'networkidle'
		| 'visible'
		| 'hidden'
}

export interface AIGoalAction extends CommonAIAction {
	command: 'goal'
	goal: string // natural language goal
}

export interface AITapAction extends CommonAIAction {
	command: 'tap'
	selector: string
}

export interface AIHoverAction extends CommonAIAction {
	command: 'hover'
	selector: string
}

export interface AIDragAction extends CommonAIAction {
	command: 'drag'
	sourceSelector: string
	targetSelector: string
}

export interface AITypeAction extends CommonAIAction {
	command: 'type'
	selector: string
	text: string
}

export interface AIKeyboardPressAction extends CommonAIAction {
	command: 'keyboard_press'
	keys: string[]
}

export interface AIScrollAction extends CommonAIAction {
	command: 'scroll'
	selector?: string
	direction: 'up' | 'down' | 'left' | 'right'
	amount?: number // pixels or percent
}

export interface AIScrollToAction extends CommonAIAction {
	command: 'scroll_to'
	selector?: string
	edge: 'top' | 'bottom' | 'left' | 'right'
}

export interface AIWaitAction extends CommonAIAction {
	command: 'wait'
	duration: number // milliseconds
}

export interface AIOpenLinkAction extends CommonAIAction {
	command: 'open_link'
	url: string
}

export interface AIZoomAction extends CommonAIAction {
	command: 'zoom'
	zoomLevel: number // e.g. 1.0 = 100%, 2.0 = 200%
	selector?: string // optional, for zooming a specific element
}

export interface AIMultitouchAction extends CommonAIAction {
	command: 'multitouch'
	events: Array<{
		type: 'pinch' | 'spread' | 'rotate' | 'swipe'
		start: { x: number; y: number }
		end: { x: number; y: number }
		fingers?: number // default 2
		angle?: number // for rotate
		amount?: number // for pinch/spread (pixels or percent)
	}>
	selector?: string // optional, for targeting a specific element
}

export interface AIGestureAction extends CommonAIAction {
	command: 'gesture'
	gestureType:
		| 'swipe'
		| 'flick'
		| 'longpress'
		| 'doubletap'
		| 'press'
		| 'pan'
		| 'rotate' // exclude 'pinch' and 'zoom' to avoid overlap
	start: { x: number; y: number }
	end?: { x: number; y: number }
	duration?: number // ms, for longpress or press
	fingers?: number // default 1
	angle?: number // for rotate
	selector?: string // optional, for targeting a specific element
}

export interface AIGoToTabAction extends CommonAIAction {
	command: 'go_to_tab'
	description: string
}

/**
 * AISetValueAction: Set the value of an input or element.
 */
export interface AISetValueAction extends CommonAIAction {
  command: 'set_value'
  selector: string
  value: string | number | boolean
}

/**
 * AIAssertAction: Assert a condition on the UI or data.
 */
export interface AIAssertAction extends CommonAIAction {
  command: 'assert'
  assertion:
	| { type: 'visible'; selector: string }
	| { type: 'not_visible'; selector: string }
	| { type: 'text_equals'; selector: string; value: string }
	| { type: 'value_equals'; selector: string; value: string | number | boolean }
}

/**
 * AIActionType: Accepts any of the known action types, or a custom command with arbitrary params.
 * This enables extension with custom commands and parameters.
 */
export type AIActionType =
	// stochastic (random) actions
	| AIGoalAction
	// deterministic actions
	| AITapAction
	| AIWaitAction
	| AIHoverAction
	| AIDragAction
	| AITypeAction
	| AIKeyboardPressAction
	| AIScrollAction
	| AIScrollToAction
	| AIOpenLinkAction
	| AIZoomAction
	| AIMultitouchAction
	| AIGestureAction
	| AIGoToTabAction
	| CustomAIAction
	| AISetValueAction
	| AIAssertAction

/**
 * CustomAIAction: Allows any string as command and arbitrary params.
 */
export interface CustomAIAction extends CommonAIAction {
	command: string // any string
	[name: string]: any // allow arbitrary params
}

Control general de la estructura

UAP usa conceptos de esquema conocidos para que las definiciones sean claras y extensibles:

  • properties: define los atributos de un objeto.
  • anyOf: admite varios tipos o estructuras posibles.
  • required: especifica los campos obligatorios.
  • type: restringe el tipo de dato de un valor.
  • default: aporta un valor por defecto.
  • item_count_range: controla la longitud mínima y máxima de un array.

Uso de herramientas

UAP también permite describir llamadas a herramientas y funciones de forma estructurada:

{
	"tool_choice": { "function": { "name": "" } },
	"tools": [
		{
			"function": {
				"description": "",
				"name": "",
				"parameters": {}
			},
			"type": "function"
		}
	]
}

Esta estructura define cómo se describen herramientas y funciones dentro de UAP.

Mantenimiento y versionado

  • version: v25.1
  • Licencia open source: Apache License 2.0
  • La IA evoluciona rápido, pero intentamos que los cambios sean previsibles:
    • Como máximo, 1 cambio rompedor cada 2 meses, cuando necesites volver a descargar el archivo del protocolo de automatización.
  • Graceful fallback: si un entorno no soporta cierta acción, las apps compatibles con UAP deberían garantizar que tu automatización no se rompa de forma inesperada.