Web automation
Botream drives web applications through Playwright in Chrome, Edge or Firefox: you open a browser with the browser command and work with page elements through the capture command.
Browsers
browser --action:open starts a browser on the agent machine. Choose it with --browser:
| Value | Browser |
|---|---|
default |
The agent machine's default browser. When it cannot be automated, Edge is used. |
chrome |
The installed Google Chrome. |
edge |
The installed Microsoft Edge. |
firefox |
Playwright's own Firefox build, downloaded once on first use. |
Chrome and Edge use the browsers already installed on the machine, so there is no browser driver to keep up to date. Each browser a task opens gets a fresh profile: no cookies, saved logins or extensions from your own browsing.
browser --action:open --url:"https://shop.example.com" --browser:edge --output:shop
Headless browsers
--headless:true runs the browser without a window. It is useful for reading data in the background, but nothing is visible on the agent's screen.
Visible browsers stay open
A visible Chrome or Edge window is left open when the run ends, so you can see where the task stopped and capture more elements in it. Close it with browser --action:close (for example in a finally section) when the task should clean up after itself. Headless browsers and Firefox are always closed when the run ends.
Tip: While you build a task, run the first few lines once, then capture the next elements directly in the browser the task left open.
In visible browsers, the agent shows what it does: before each element action, a pointer glides to the element, which gets an orange frame with the action's name ("Click", "Type") for about a second. The real mouse is not moved.
Browser variables
--output on browser --action:open stores the page in a variable. Every other web command points at it with --browser:$name$, so you can work with several pages at once:
browser --action:open --url:"https://shop.example.com" --output:shop
browser --action:open --url:"https://erp.local" --output:erp
capture --browser:$shop$ --action:gettext --dompath:"#price" --output:price
capture --browser:$erp$ --action:settext --dompath:"#amount" --value:$price$
browser --browser:$shop$ --action:close
Without --browser, a command acts on the page used last.
The other browser actions are navigate, refresh, back, forward, scroll, screenshot (the whole page, also when headless), getcurrenturl, gettitle, executejs and close, plus the tab, dialog and cookie actions below.
The capture command
capture works with one element of a page. Pick the action with --action:
| Group | Actions |
|---|---|
| Mouse | click, doubleclick, rightclick, hover |
| Input | settext (replaces the field's text), clear, select, check, uncheck, sendkeys, focus, submit |
| Read | gettext, getproperty, getattribute, exists, gettable, extract |
| Write | setproperty |
| Wait and scroll | waitfor, scrollto, scroll |
| Files | upload, download, screenshot |
capture --browser:$shop$ --action:settext --dompath:"//input[@name='email']" --value:"user@test.com"
capture --browser:$shop$ --action:select --dompath:"//select[@id='country']" --value:"Turkey"
capture --browser:$shop$ --action:getproperty --dompath:"//h1" --property:text --output:pageTitle
capture --browser:$shop$ --action:exists --dompath:"//div[@class='error']" --output:hasError
--property for getproperty takes text, value, innerhtml, outerhtml or any HTML attribute. Every element action waits for the element up to --timeout (30 seconds by default) and can be repeated with --retry and --retryinterval.
Capturing elements
You rarely write selectors yourself. Select a capture command in the editor and click Capture next to Selector; the Capture web element dialog opens and asks you to switch to the browser and click the element.
- Elements are highlighted as you move the mouse. Press Esc to cancel: Botream asks Cancel the capture? first (Enter cancels, Esc again keeps capturing).
- Where you can capture: in Chrome or Edge with the Botream Element Capture extension installed (see Install the extension), and in the Chrome and Edge windows your tasks opened. Those run with a fresh profile without the extension, so the agent shows the picker in them itself.
- Which page comes forward: when the command has a
--browser:$page$whosebrowser --action:openhas a fixed address, that tab is brought to the front. - Requirements: the Botream Agent must run on the computer you are working on. When several agents are online, the dialog asks you to choose the one on this computer.
The capture fills Selector (--dompath), the Object properties table and a screenshot of the page with the element framed in red; click the screenshot to see it in full.
Note: Captures from older agents or extensions come without object properties. The dialog then lists the selectors it found, marked Recommended or Not unique; choose one and click Use selected.
UI technology
Before you click Capture on a capture command, choose the technology in the box next to it. The choice is kept in the command as --technology.
| Technology | Captures and finds |
|---|---|
| Auto (default) | Page elements as HTML. Clicks on the browser's own dialogs and windows (the file chooser, alerts, the address bar, the PDF viewer's toolbar) are captured with UI Automation, and the command switches to UI Automation by itself. Tabs and the title bar stay usable, so you can switch tabs while capturing. |
| HTML | Page elements only, through the extension. |
| UI Automation | The browser's own windows and dialogs only, with the agent's desktop picker. |
A UI Automation element is stored like a desktop element:
- Selector (
--dompath) holds a desktop locator such asname=Open,automationid=…or an XPath. - Window (
--window) is a window variable for the browser window or dialog, such asset --name:window1 --type:window --path:chrome.exe --title:"* - Google Chrome". The main window is matched by the browser's name because its title changes with every page. - Object properties are the desktop properties (Name, AutomationId, control type…).
When the task runs, the command works as a desktop command, so every agent runs it. It supports click, double click, right click, set text, append text, clear, check, uncheck, hover, focus, scroll to, wait for, select, get/set property, get text and exists. HTML-only actions (tables, extract, upload, download, screenshots…) are refused in the editor.
capture --action:click --technology:uia --window:$window1$ --dompath:"name=Open"
Note: Capturing the browser's own windows with Auto needs the current Botream Agent; older agents capture page elements only. UI Automation works with every agent.
Object properties
The Object properties table lists everything read from the element at capture time, each with a checkbox. Above it, Object type says what the element is (Text box, Button, Check box, Drop-down list, Link, Table cell…). The element is found by the checked properties: every one must be equal to the element's.
| Property | What it compares |
|---|---|
| HTML tag | The element type, such as input or button. |
| HTML id, HTML name, HTML type | The id, name and type attributes. |
| Inner text | The visible text, spaces collapsed. |
| HTML class | Every listed class must be present, in any order. |
| placeholder, aria-label, title, alt, role, for, data-testid | The attributes of the same name. |
| Value attribute, Link (href), Source (src) | The value, href and src attributes. |
| DOM XPath | The full position in the page. It breaks when the layout changes, so leave it unchecked unless nothing else works. |
| Index | When several elements match the other checked properties, which one (1 = first on the page). |
- Wildcards: for the parts that change, type a
*; it matches anything. An inner text ofInvoice*finds "Invoice 2026-10-06",*total*any text containing total,*.pdfa link ending in .pdf. - Older tasks: comparisons chosen before (Contains, Starts with, Not equal to…) keep working and show as a tag next to the property; close the tag to compare as equal.
- Variables:
$variables$work in values, for example an inner text of$customerName$. - More attributes: type a name in Another attribute, e.g. data-id and click Add.
- Default choice: the capture checks the tag and the identifying properties (a stable id, name or test id first), adds more while the element is not unique, and uses the index only as a last step.
The Selector is rebuilt from the checked properties on every change. If you edit the selector by hand, the table is no longer used; click Use properties to rebuild the selector from it.
Tip: Check properties that describe what the element is (its label, name or test id), not where it is. See Finding elements reliably.
Frames
An element inside an iframe needs --frame with the iframe's selector. Separate nested frames with >>:
capture --browser:$shop$ --action:click --frame:"#payment" --dompath:"#pay"
capture --browser:$shop$ --action:settext --frame:"#checkout >> #card" --dompath:"#number" --value:$cardNo$
Without --frame, the element is looked for in the page itself. wait --type:element and wait --type:elementgone take --frame too.
Tabs and pop-ups
browser --browser:$shop$ --action:newtab --url:"https://shop.example.com/orders"
browser --browser:$shop$ --action:switchtab --title:"*Invoice*" --timeout:10
browser --browser:$shop$ --action:switchtab --url:"*orders/new*"
browser --browser:$shop$ --action:gettabs --output:tabs
browser --browser:$shop$ --action:closetab
newtabandswitchtabmake that tab the current one:--browser:$shop$means that tab from then on.switchtabmatches--titleand/or--url(wildcards) among the browser's tabs and pop-ups, and waits up to--timeoutfor it to appear.closetabcloses the current tab; the previous one becomes current. It fails on the last tab (useclose).gettabsreturns records withTitle,UrlandIsCurrent.
Waits
wait checks every 250 ms until something happens on the page:
wait --type:element --browser:$shop$ --dompath:"//div[@id='loaded']" --timeout:30
wait --type:elementgone --browser:$shop$ --dompath:".spinner"
wait --type:pageload --timeout:60
wait --type:url --value:"*dashboard*" --timeout:30 --failontimeout:true
When the time is up, the task goes on with a warning in the log and --output receives false. With --failontimeout:true the command fails instead, and the nearest catch handles it. capture --action:waitfor waits for one element in the same way an element action does.
Checking the page in a condition
To branch on what the page shows, give if or elseif the condition type elementexists (the element is shown) or elementnotexists (hidden or not on the page). It replaces capture --action:exists followed by if --type:boolean:
if --type:elementexists --browser:$shop$ --dompath:"//div[@class='error']" --timeout:3
capture --browser:$shop$ --action:gettext --dompath:"//div[@class='error']" --output:problem
throw --type:business --message:"The shop refused the order: $problem$"
endif
if --type:elementnotexists --browser:$shop$ --dompath:".spinner" --timeout:30
log --message:"The page is ready"
endif
The properties panel shows the same Capture button, Object properties table and --frame as capture, and the fallback locators of the table are tried too. --timeout (default 0) waits up to that many seconds for the element to appear or go away before deciding; a missing element is an answer, never an error. See if / elseif / else for all condition types.
Downloads and uploads
capture --browser:$shop$ --action:download --dompath:"#export" --path:"C:\Downloads" --output:file
capture --browser:$shop$ --action:upload --dompath:"input[type=file]" --file:"C:\a.pdf, C:\b.pdf"
downloadclicks the element and saves the file the site downloads.--pathis a file name, or a folder (the site's file name is used).--outputreceives the saved path.uploadsets one or more files (comma-separated) on a file input, or hands them to the file dialog the element opens when clicked.
Dialogs
Pages' alert, confirm and prompt dialogs are dismissed (Cancel) unless you say otherwise:
browser --action:ondialog --accept:true --text:"duplicate order"
capture --browser:$shop$ --action:click --dompath:"#save"
browser --action:getlastdialog --output:message
ondialog applies from then on: --accept answers OK (true, the default) or Cancel (false); --text is typed into prompt dialogs. getlastdialog returns the message of the last dialog.
Cookies
browser --browser:$shop$ --action:setcookie --name:session --value:$token$ --domain:"example.com"
browser --browser:$shop$ --action:getcookies --output:cookies
browser --browser:$shop$ --action:clearcookies
getcookies returns records with Name, Value, Domain, Path and Expires. Without --domain, setcookie sets the cookie for the current page's site.
Reading a table into a datatable
gettable reads an HTML table into a datatable variable. Capture the table, any of its cells, or an element that contains it:
capture --browser:$shop$ --action:gettable --dompath:"#orders" --output:orders
loop --type:datatable --table:$orders$ --variable:row
log --message:"Order $row.Number$: $row.Total$"
endloop
- With
--header:true(the default), the last row of the table head, or else the first row, names the columns. Empty names becomeColumnN; repeated names get_2. - With
--header:false, the columns areColumn1,Column2… and every row is data. - Cell texts are trimmed. A cell spanning several columns or rows is repeated in each.
- The command fails when there is no table at that element.
Extracting data from lists and multiple pages
Many pages show their data as repeating items rather than an HTML table: product cards, search results, rows of a list built from divs, often spread over several pages with a Next button. extract reads them into a datatable, one row per item, page after page — like Data scraping in UiPath or Extract data in Automation Anywhere. You make it with the Extract data wizard; no selectors to write.
Starting the wizard. Press Ctrl+K and type extract data, or open the Web group of the palette and click Extract data. A capture --action:extract block is added and the wizard opens. On an existing block, click Edit in wizard under Columns (or Wizard next to Selector). Open the page in Chrome first (or run the task up to it), so the wizard can show what it finds.
- Items. Click Click the first item, switch to the browser and click one item — the whole product card, the whole search result. The wizard then asks for a second item of the same kind. From the two it makes a selector that matches every item:
…/ul/li[1]/divand…/ul/li[3]/divbecome…/ul/li/div. When the items also share a class, or sit under an element with an id, those choices are offered too, each with the number of items it finds on the page. "N items found on the page" confirms the choice. - Values. Click Click values and click, in one item, each value you want: the title, the price, the link, the picture. Each click adds a column with a suggested name (from the element's label or class), where it is inside the item, and what to read: the text, the address of a picture (
src) or the value of a field. A link reads its text; choose Link address (href) to get the address. Press Esc in the page when you have them all. In the list you can rename columns (letters, digits and_, so they become$row.Price$), change what is read (any attribute name works too), edit the path, move columns up or down and remove them. The first rows of the page show below as a preview. - Pages (optional). Choose The data is on several pages, click Click the Next button and click the page's Next button or link. Set how many pages to read at most (10 by default).
- Preview. Check the first rows, then click Finish. The wizard writes
--dompath,--columns,--nextand--maxpagesand names the resultresults(change Output if you like).
capture --browser:$shop$ --action:extract --dompath:"//div[@id='results']/ul/li/div" --columns:[{"name":"Title","path":".//h3","read":"text"},{"name":"Price","path":".//span[@class='price']","read":"text"},{"name":"Link","path":".//a","read":"href"}] --next:"//a[normalize-space()='Next']" --maxpages:10 --output:products
loop --type:datatable --table:$products$ --variable:row
log --message:"$row.Title$ costs $row.Price$"
endloop
- Columns are a JSON list:
name,path(where the value is inside the item: an XPath starting with., where.is the item itself, or a CSS selector) andread(text,value,href,src,htmlor any attribute name). The properties panel shows them as a list; Edit as text shows the JSON. - Missing values are empty cells, never an error. When no item is found at all, the result is an empty table with the columns and the log says so.
- Pages: after each page the robot clicks
--nextand waits until the items change (a new page loaded, or the list redrawn by the page). It stops when the Next button is missing, hidden or disabled, after--maxpagespages, when the items did not change within--timeout, or when a page shows the same rows again. A Load more button that adds rows below the earlier ones works too: each row is read once. --maxrowslimits the number of rows (0, the default, reads all).--framereads items inside an iframe.- The live preview works in Chrome or Edge with the Botream extension and in browsers your tasks opened; it reads the tab with the page you clicked in. Without it the wizard still works — run the task to see the result.
extractneeds a current Botream Agent; an older agent refuses the task with a message to update it.
Tip: The template Collect search results from several pages into Excel (New task → Start from a template) is a ready-made example: open the search page, extract, write to Excel.
Scrolling
| Command | What it does |
|---|---|
browser --action:scroll --amount:-5 |
Turns the mouse wheel over the middle of the page. Pages that load more as you scroll react too. |
capture --action:scroll --dompath:… --amount:-3 |
Turns the wheel over an element: lists, panels and tables that scroll inside the page. |
capture --action:scrollto --dompath:… |
Scrolls until the element is in view. |
--amount is in wheel notches of about 100 pixels: positive scrolls up, negative down. Both wheel commands wait until the scrolling has settled.
Sending keys
capture --action:sendkeys focuses the element and presses keys there as the keyboard would:
capture --browser:$shop$ --action:sendkeys --dompath:"#search" --keys:"laptop[ENTER]"
capture --browser:$shop$ --action:sendkeys --dompath:"#grid" --keys:"[CTRL+A][CTRL+C]"
- Special keys and shortcuts go in brackets:
[TAB],[ESC],[DOWN],[CTRL+A]. Use[[for a literal[. The Insert key menu next to Keys to send lists the common ones. - Unlike
settext, the field is not cleared first. - Keys after one that moves the focus (such as
[TAB]) go where the focus went.
Tip: Use
settextto fill a field; usesendkeysfor shortcuts, rich text editors and fields that react to each key press.
Related pages
- Finding elements reliably: fallback locators, anchors and self-healing.
- Recording: turn your own clicks and typing into commands.
- Error handling:
try/catch, retries and failure details.