ifURI examples
← all examples

40 — local portals suite for autonomous browser testing

This example adds several local-only portals for testing autonomous browser work:

HostPortalAction route
crm.localfake CRMportal://crm.local/lead/command/create
support.localfake support deskportal://support.local/ticket/command/create
shop.localfake shop adminportal://shop.local/order/command/create
docs.localfake docs/wikiportal://docs.local/doc/command/create

Every portal has a login page backed by .env, a form, a records panel, and an /api/records endpoint for verification. Chrome maps the selected *.local host to 127.0.0.1, so no /etc/hosts edit is needed.

One Prompt

./run_prompt.sh 'crm: utwórz lead "Acme z promptu NL"'

Other prompts:

./run_prompt.sh 'support: zgłoszenie "Nie działa lokalny worker"'
./run_prompt.sh 'shop: zamów produkt "URI Test Subscription" qty 3'
./run_prompt.sh 'docs: dokument "Notatka z testu lokalnej autonomii"'

Run all four:

./run_all.sh

Domain Loop Prompt

For loop testing, put the local domain directly in the prompt:

./run_loop.sh 'support.local 3 razy zgłoszenie "Nie działa worker"'

Other domains:

./run_loop.sh 'crm.local 5 razy utwórz lead "Acme Loop"'
./run_loop.sh 'shop.local 2 razy zamów produkt "URI Test Subscription" qty 3'
./run_loop.sh 'docs.local 4 razy dokument "Notatka z pętli autonomicznej"'

The loop is bounded. By default it runs 3 iterations when the prompt does not include a count, and it caps the requested count at 10. Domains must be one of the known local fixtures: crm.local, support.local, shop.local, docs.local.

What It Uses

The wrapper uses built-in urirun pieces:

python3 -m urirun.runtime.v2 compile bindings.json --out .state/local-portals.registry.json

python3 -m urirun.runtime.v2 agent run .state/local-portals.registry.json \
  --planner portal_autonomy:planner \
  --allow 'portal://**' \
  --allow-commands \
  --goal 'support: zgłoszenie "Nie działa lokalny worker"'

portal_autonomy:planner maps NL text to one typed portal://... route and payload. The handler starts the local portal server, logs in with .env, fills the form in a real local Chrome session over CDP, submits, then verifies through /api/records.

Files

Boundary

These portals are intentionally local fixtures. They are for testing selectors, closed-loop repair, OCR, and NL-to-URI planning without external side effects.

Files

.env.env.example.gitignoreREADME.mdbindings.jsondomain_loop.pyportal_autonomy.pyportal_server.pyrun_all.shrun_loop.shrun_prompt.shtest_portals.py

View on GitHub →