Skip to main content

Release checks

Teams ship a web app several times a week, and the critical journeys such as sign in, search and checkout have to keep working. Classic browser tests break whenever a button moves or a class name changes, so somebody spends the sprint repairing selectors instead of writing tests.

A computer use agent looks at the rendered page the way a tester does. You describe the journey in words, and the agent finds the elements on screen.

Staging appafter deployscreenshotComputer agentclaude-sonnet-5actionclick, typescroll, keysReportpass or failrepeat until the journey is finished

The check

Point the agent at the staging URL and describe the journey.

from intelli.function.computer_agent import ComputerAgent
from intelli.function.browser_env import PlaywrightBrowserEnvironment

env = PlaywrightBrowserEnvironment(start_url="https://staging.example.com", headless=True)

agent = ComputerAgent(
api_key=ANTHROPIC_KEY,
provider="anthropic",
model="claude-sonnet-5",
environment=env,
max_iterations=20,
log=True,
)

try:
result = agent.run(
"Search for a laptop stand, open the first result, add it to the cart, "
"then report the cart total and whether the checkout button is enabled."
)
print(result["output"])
finally:
env.close()

Keep the agent read only

A smoke check should never place a real order. The on_action hook blocks any action you did not intend, and it blocks the action as well if the hook itself raises.

BLOCKED_WORDS = ["place order", "pay now", "confirm purchase"]

def guard(action):
text = str(action.get("text", "")).lower()
return not any(word in text for word in BLOCKED_WORDS)

agent = ComputerAgent(
api_key=ANTHROPIC_KEY,
provider="anthropic",
environment=env,
on_action=guard,
)

Run the checks in one flow

Each journey is a task, so the whole suite runs in a single flow and a final text agent turns the outputs into a release note.

import asyncio
from intelli.flow import Agent, Task, Flow, TextTaskInput

def journey_agent(mission):
return Agent(
agent_type="computer",
provider="anthropic",
mission=mission,
model_params={
"key": ANTHROPIC_KEY,
"model": "claude-sonnet-5",
"start_url": "https://staging.example.com",
"max_iterations": 20,
},
)

sign_in = Task(
TextTaskInput("Open the sign in page and report whether the form accepts a demo account."),
journey_agent("check the sign in journey"),
log=True,
)

search = Task(
TextTaskInput("Search for a laptop stand and report how many results appear."),
journey_agent("check the search journey"),
log=True,
)

summary = Task(
TextTaskInput("Write a short release check summary. Mark every failing journey clearly."),
Agent(
agent_type="text",
provider="openai",
mission="summarize release checks",
model_params={"key": OPENAI_KEY, "model": "gpt-5.5"},
),
log=True,
)

flow = Flow(
tasks={"sign_in": sign_in, "search": search, "summary": summary},
map_paths={"sign_in": ["summary"], "search": ["summary"], "summary": []},
log=True,
)

results = asyncio.run(flow.start())
print(results["summary"]["output"])

Why it helps

  • The checks survive a redesign, because the agent reads the screen instead of a selector.
  • A new journey costs one sentence, so product people can add checks too.
  • The same flow runs against staging and production by changing start_url.