Browser Automation

The browser is a first-class OcaltQL object. BROWSER OPEN creates a session, captured with SET. Every subsequent operation is subject-first — BROWSER ?session VERB ... SET ?result — exactly like every other domain in OcaltQL. Multiple sessions run in true parallel using the same AND/Multi/COLLAPSE mechanism used everywhere else in the language.

Every example on this page runs as written against /tutorial/fixture.html — a live page carrying every selector used below, plus an automatic /api/data request so the network examples have real traffic to match. Press Try it and you get output, not an error.

Session Lifecycle

Open, Navigate, Close
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session NAVIGATE "https://ql.ocalt.com/tutorial/introduction" SET ?session
AFTER BROWSER ?session CLOSE

Interaction

Click, Type, Select, Hover, Upload, Clear
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session CLICK "#menu" SET ?session
AFTER BROWSER ?session TYPE "#email" WITH "user@example.com" SET ?session
AFTER BROWSER ?session SELECT "#country" WITH "South Africa" SET ?session
AFTER BROWSER ?session HOVER "#dropdown" SET ?session
AFTER BROWSER ?session UPLOAD "#file" WITH "/root/document.pdf" SET ?session
AFTER BROWSER ?session CLEAR "#search" SET ?session
AFTER BROWSER ?session CLOSE
Scroll
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session SCROLL X 0 Y 500 SET ?session
AFTER BROWSER ?session SCROLL X 200 Y 300 SET ?session
AFTER BROWSER ?session CLOSE
Click by Coordinate
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session CLICK AT X 63 Y 125 SET ?element
AFTER EMIT "Clicked: " & ?element("tag") & " #" & ?element("id")
AFTER BROWSER ?session CLOSE
CLICK AT X n Y n clicks a raw pixel coordinate on the page rather than a CSS selector — the counterpart to selector-based CLICK "#id". It is the tool for driving the browser visually: when you are watching a live snapshot of the window and want to click a spot you can see, but have no clean selector for it. Coordinates are relative to the top-left of the viewport, in the same X n Y n form used by SCROLL.

Reading and Extraction

Read Raw HTML
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session READ ".itemlist" SET ?html
AFTER BROWSER ?session CLOSE
AFTER EMIT ?html
Structured Extraction
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session EXTRACT ".price" AS "text" SET ?text
AFTER BROWSER ?session EXTRACT "table" AS "json" SET ?data
AFTER BROWSER ?session EXTRACT "a.link" AS "attribute:href" SET ?href
AFTER BROWSER ?session EXTRACT ".item" AS "count" SET ?count
AFTER BROWSER ?session CLOSE
Evaluate JavaScript
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session EVALUATE "document.title" SET ?title
AFTER BROWSER ?session EVALUATE "document.querySelectorAll('a').length" SET ?linkCount
AFTER BROWSER ?session CLOSE
AFTER EMIT ?title & " — " & ?linkCount & " links"

Waiting

Fixed Wait
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session CLICK "#load-more" SET ?session
AFTER BROWSER ?session WAIT 2 SET ?session
AFTER BROWSER ?session READ ".results" SET ?html
AFTER BROWSER ?session CLOSE
Conditional Wait — For an Element
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session WAIT FOR "#result" SET ?session
AFTER BROWSER ?session READ "#result" SET ?html
AFTER BROWSER ?session CLOSE
Conditional Wait — For Specific Text
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session CLICK "#load-more" SET ?session
AFTER BROWSER ?session WAIT FOR "#status" TO "Complete" SET ?session
AFTER BROWSER ?session CLOSE
AFTER EMIT "status reached Complete"
Conditional Wait — For a Network Request
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session WAIT FOR NETWORK "*/api/data*" SET ?session
AFTER BROWSER ?session CLOSE

Navigation History

Back, Forward, Reload
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session NAVIGATE "https://ql.ocalt.com/tutorial/introduction" SET ?session
AFTER BROWSER ?session BACK SET ?session
AFTER BROWSER ?session FORWARD SET ?session
AFTER BROWSER ?session RELOAD SET ?session
AFTER BROWSER ?session CLOSE

Focus and Tab

Tab Through Fields
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session TAB NEXT SET ?session
AFTER BROWSER ?session TAB PREV SET ?session
AFTER BROWSER ?session FOCUS CHECK AS "id" SET ?focusedId
AFTER BROWSER ?session CLOSE

Session & State

Local Storage
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session STORAGE WRITE "theme" WITH "dark" SET ?session
AFTER BROWSER ?session STORAGE READ "theme" SET ?value
AFTER BROWSER ?session CLOSE
Cookies
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session COOKIES SET ?cookies
AFTER BROWSER ?session COOKIE WRITE "session_id" WITH "abc123" SET ?session
AFTER BROWSER ?session CLOSE
HTTP Basic Auth
BROWSER OPEN "https://postman-echo.com/get" SET ?session
AFTER BROWSER ?session AUTH "myuser:mypass" SET ?session
AFTER BROWSER ?session NAVIGATE "https://postman-echo.com/get" SET ?session
AFTER BROWSER ?session EVALUATE "document.body.innerText" SET ?echo
AFTER BROWSER ?session CLOSE
AFTER EMIT ?echo

Viewport and Device

Custom Viewport
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session VIEWPORT WIDTH 1920 HEIGHT 1080 SET ?session
AFTER BROWSER ?session CLOSE
Device Emulation
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session MOBILE "iPhone 14" SET ?session
AFTER BROWSER ?session CLOSE

Output and Capture

Screenshot
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session SCREENSHOT "/root/snap.png" SET ?path
AFTER BROWSER ?session CLOSE
AFTER FILE SHARE ?path SET ?url
AFTER EMIT ?url
Live View — Latest Frame to a Fixed Path
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session VIEW SET ?path
AFTER BROWSER ?session CLOSE
AFTER EMIT ?path
(* Output: /root/browser/now.png *)
BROWSER ?session VIEW captures the current browser window as a single snapshot, writes it to the fixed path /root/browser/now.png, and returns that path. Unlike SCREENSHOT, which writes to a caller-chosen path, VIEW always targets the same known location — so anything watching /root/browser/now.png always sees the most recent frame. There is no background loop and nothing to stop: each call to VIEW simply overwrites that one file with the window as it looks at that instant. Call it again whenever you want a fresh frame.

Visual / Ghost Browsing

The ghost-browse loop drives the browser by eye rather than by selector. Open a session, VIEW to drop the current window at /root/browser/now.png, FILE SHARE that path so you can watch it, then decide a spot from what you see and CLICK AT those coordinates. Call VIEW again to see the result, and repeat — navigate, look, decide, click, look again.
Ghost Browse — View, Decide, Click
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session VIEW SET ?path
AFTER FILE SHARE ?path SET ?url
AFTER EMIT "Watch here: " & ?url
(* You look at the shared frame and decide where to click. *)
AFTER BROWSER ?session CLICK AT X 63 Y 125 SET ?element
AFTER EMIT "Clicked: " & ?element("tag")
AFTER BROWSER ?session VIEW SET ?path
AFTER FILE SHARE ?path SET ?url2
AFTER EMIT "After the click: " & ?url2
AFTER BROWSER ?session CLOSE
PDF Render
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session PDF "/root/invoice.pdf" SET ?path
AFTER BROWSER ?session CLOSE
Trigger a Download
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session DOWNLOAD "https://ql.ocalt.com/tutorial/api/data.json" TO "/root/file.zip" SET ?path
AFTER BROWSER ?session CLOSE
Network Log
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session NETWORK LOG SET ?har
AFTER BROWSER ?session CLOSE
Intercept a Network Request
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session INTERCEPT "*/api/data*" SET ?captured
AFTER EMIT ?captured("url")
AFTER EMIT ?captured("method")
AFTER BROWSER ?session CLOSE

Live Streaming

Stream Screenshots to a Channel
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session STREAM TO "live-chart"
AFTER BROWSER ?session WAIT 5 SET ?session
AFTER BROWSER ?session CLOSE
(* Subscribers on the "live-chart" channel receive base64-encoded PNG frames *)

Parallel Sessions

Multiple browser sessions run in true parallel using the same AND/Multi/COLLAPSE mechanism as every other domain in OcaltQL. Each AND-chained statement writing to the same target variable builds a multivariable branch. No loop is needed — the branches exist natively.

Extracting from Three Sessions in Parallel
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session1
AFTER BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session2
AFTER BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session3
AFTER BROWSER ?session1 EXTRACT ".price" AS "text" SET ?price
AND BROWSER ?session2 EXTRACT ".price" AS "text" SET ?price
AND BROWSER ?session3 EXTRACT ".price" AS "text" SET ?price
AFTER BROWSER ?session1 CLOSE
AFTER BROWSER ?session2 CLOSE
AFTER BROWSER ?session3 CLOSE
AFTER COLLAPSE ?price SET ?prices
AFTER EMIT ?prices

Reading What You Clicked

CLICK AT returns the element that was under the coordinate, not just the session — a blind pixel click becomes self-describing. The returned object carries tag, id, class, name, href, value, text and html, plus session, which is why SET ?session still chains as before.

Identify a Target Before Acting
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session CLICK AT X 63 Y 125 SET ?element
AFTER EMIT "tag:  " & ?element("tag")
AFTER EMIT "id:   " & ?element("id")
AFTER EMIT "href: " & ?element("href")
AFTER EMIT "text: " & ?element("text")
AFTER BROWSER ?session CLOSE

Counting and Measuring

Count Matches Without Reading Them
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session EXTRACT ".item" AS "count" SET ?items
AFTER BROWSER ?session EXTRACT ".price" AS "count" SET ?prices
AFTER BROWSER ?session EVALUATE "document.links.length" SET ?links
AFTER BROWSER ?session CLOSE
AFTER EMIT ?items & " items, " & ?prices & " prices, " & ?links & " links"

Watching Traffic End to End

The network verbs compose: wait for a request to happen, read the whole log, then pull the one you care about back out of it.

Wait, Log, Then Inspect
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session WAIT FOR NETWORK "*/api/data*" SET ?session
AFTER BROWSER ?session NETWORK LOG SET ?log
AFTER COUNT ?log SET ?total
AFTER BROWSER ?session INTERCEPT "*/api/data*" SET ?api
AFTER BROWSER ?session CLOSE
AFTER EMIT ?total & " requests; the api call was " & ?api("method") & " " & ?api("url")

Keyboard Navigation

Tab Through and Report Focus
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session TAB NEXT SET ?session
AFTER BROWSER ?session FOCUS CHECK AS "tag" SET ?tag
AFTER BROWSER ?session TAB NEXT SET ?session
AFTER BROWSER ?session FOCUS CHECK AS "id" SET ?id
AFTER BROWSER ?session CLOSE
AFTER EMIT "first: " & ?tag & " then: " & ?id

Full Pipeline Example

Login Flow
BROWSER OPEN "https://ql.ocalt.com/tutorial/fixture.html" SET ?session
AFTER BROWSER ?session TYPE "#email" WITH "user@example.com" SET ?session
AFTER BROWSER ?session TYPE "#password" WITH "secret" SET ?session
AFTER BROWSER ?session CLICK "#submit" SET ?session
AFTER BROWSER ?session WAIT FOR ".welcome-msg" SET ?session
AFTER BROWSER ?session EXTRACT ".welcome-msg" AS "text" SET ?msg
AFTER BROWSER ?session CLOSE
AFTER EMIT ?msg
BROWSER OPEN creates a session captured with SET. Every subsequent verb is subject-first: BROWSER ?session VERB .... Multiple sessions run in true parallel via AND-chained assignment to the same target, producing a native multivariable — no explicit loop required, only a final COLLAPSE.