Tutorial

Build a Self-Running QA Testing Bot with the Computer Use API

Sarah Chen||12 min
Cmd+V

QA teams spend hours clicking through flows to catch regressions. Scripts break when UI changes or selectors become stale. The computer use API lets you build a self-running QA agent that sees the screen like a human and performs actions directly on the browser, desktop, or terminal. You define a task, the agent drives a real machine, and it reports success or failure.

How it works

You start a machine with POST /v1/machines. The response includes a machine_url and device_id. Then you create a task run with POST /v1/runs. The agent runs on that machine, takes screenshots, and performs actions until it finishes. The task run has a status field that can be queued, running, awaiting_human, succeeded, failed, cancelled, or timed_out. Each agent step costs $0.05.

python
import os
import requests

API_KEY = os.getenv("COASTY_API_KEY")
BASE_URL = "https://coasty.ai/v1"

# Provision a cloud VM for the agent
def provision_machine():
    resp = requests.post(
        f"{BASE_URL}/machines",
        headers={"X-API-Key": API_KEY},
        json={"os": "ubuntu-22.04"}
    )
    resp.raise_for_status()
    return resp.json()

# Create a self-running QA task
def create_qa_task(machine_id, task_name, workflow):
    resp = requests.post(
        f"{BASE_URL}/runs",
        headers={
            "X-API-Key": API_KEY,
            "Content-Type": "application/json"
        },
        json={
            "machine_id": machine_id,
            "task": task_name,
            "cua_version": "v4",
            "system_prompt": "You are a QA tester. Verify the app works. Return PASS or FAIL.",
            "max_steps": 100,
            "deadline_seconds": 300,
            "on_awaiting_human": "pause"
        }
    )
    resp.raise_for_status()
    return resp.json()

# Poll for status until done
import time
def wait_for_run(run_id):
    while True:
        resp = requests.get(
            f"{BASE_URL}/runs/{run_id}",
            headers={"X-API-Key": API_KEY}
        )
        resp.raise_for_status()
        run = resp.json()
        status = run.get("status")
        if status in ("succeeded", "failed", "cancelled", "timed_out"):
            return run
        time.sleep(2)

# Example workflow DSL
workflow = {
    "version": 1,
    "steps": [
        {"type": "task", "name": "open_home", "command": "open https://example.com"},
        {"type": "task", "name": "verify_title", "command": "assert page.title === 'Example Domain'"},
        {"type": "succeed", "name": "pass"}
    ]
}

machine = provision_machine()
run = create_qa_task(machine["device_id"], "QA test", workflow)
print("Run ID", run["id"])
result = wait_for_run(run["id"])
print("Status", result["status"])

Task run fields and pricing

  • machine_id: the device ID from /v1/machines
  • task: a string describing the QA objective
  • cua_version: use 'v4' for autonomous runs with pass/fail verification
  • system_prompt: appended to the base prompt for behavior control
  • max_steps: limit steps per run
  • deadline_seconds: hard time limit
  • on_awaiting_human: pause, fail, or cancel when the agent needs a human
  • Each agent step is billed $0.05
  • POST /v1/runs starts the task
  • GET /v1/runs/{id} polls status
  • POST /v1/runs/{id}/cancel and POST /v1/runs/{id}/resume control the run

POST /v1/runs with cua_version: "v4" and pass/fail verification gives you a fully autonomous QA bot.

Where this beats brittle automation

Traditional automation relies on selectors like XPath or CSS that break when layouts change. The computer use agent sees the actual screen pixels, detects text and UI elements, and clicks or types like a human. You do not need to maintain selectors or rewrite scripts for every UI tweak. The agent works on browsers, desktops, and terminals, making your QA suite more resilient and easier to extend.

Next steps

  • Define workflows for common QA flows
  • Add assertions and retries in the workflow DSL
  • Integrate webhook URLs to notify CI/CD on pass or fail
  • Scale runs across multiple machines for parallel testing
  • Explore the free /v1/parse endpoint to convert existing PyAutoGUI scripts into structured actions

You can build a self-running QA bot that drives real browsers and desktops without brittle selectors. Start by provisioning a machine, creating a task run with cua_version v4, and polling for success or failure. Get a key at https://coasty.ai/developers and deploy your first QA agent today.

Want to see this in action?

View Case Studies
Try Coasty Free