DOM automation API
Safe named actions for real controlled tabs: read, write, wait, highlight, and guide a visible run without arbitrary code execution.
What makes this credible
RTO uses named safe DOM actions on controlled tabs instead of arbitrary injected code. That makes the behavior more explainable and easier to trust.
Best helper companions
See RTO_DOM_actions.js, RTO_form_helpers.js, and the visual cue helpers for guided runs.
Basics
- DOM actions are sent as
type:"command"messages (wrapped byRTOForm.command({ action: "...", ... }, opts)). - Most actions require
{ tabKey, selector }in the payload. - Top-frame only: DOM actions run in the controlled tab’s top frame (iframes are intentionally ignored).
- For dynamic pages, always call
waitForSelectorbeforeclick/getText/setValue.
Safety rules you will see in errors
PROTECTED_ELEMENT: the extension blocks touching its own injected UI/protected nodes.- Sensitive fields are blocked: password/hidden inputs and common credit-card/iban/password-like names.
getHtmlis sanitized/redacted and typically truncated (for safety + size limits).
Supported actions (canonical)
These are the named actions handled by the content script (called via RTOForm.command({ action: "...", ... }, opts)).
| Action | Typical payload fields | Notes |
|---|---|---|
waitForSelector | { selector, timeoutMs?, pollMs? } | Wait until an element exists. |
click | { selector } | Clicks an element (protected nodes blocked). |
focusElement | { selector } | Focus an element. |
submit | { selector } | selector must target a <form>. |
setValue | { selector, value } | Inputs/textareas/selects/contentEditable; sensitive blocked. |
typeText | { selector, text, clear?, delayMs? } | Simulated typing; sensitive blocked. |
pressKey | { key, selector? } | Dispatches key events; focuses selector if provided. |
getText | { selector, timeoutMs?, pollMs? } | Returns text; supports wait loop. |
getValue | { selector, timeoutMs?, pollMs? } | Reads value if present (protected blocked). |
getAttr | { selector, name, timeoutMs?, pollMs? } | Reads an attribute (protected blocked). |
getHtml | { selector?, property?, allowBodyFallback? } | Sanitized outerHTML; redacts inputs; typically truncated. |
setInnerHtml | { selector, html } | Sanitizes: removes scripts/iframes/handlers/javascript: URLs. |
setChecked | { selector, checked } | Checkbox/radio only. |
selectOption | { selector, value? , label? , index? , values? } | Supports multi-select via values. |
selectSetValue | { selector, value } | Set a <select> by value. |
highlight | { selector, color?, ms?, clear?, mode? } | Debug highlight, can clear. |
domSetStyle | { selector, style } | Allow-list of safe CSS props only. |
injectCss | { css } | Injects a style tag. |
addClass | { selector, className } | Adds a class. |
overlayCreate | { x?, y?, size?, color?, pulse?, appearance? } | Creates a visible overlay cursor (ring or PNG) and may also apply a real CSS cursor via appearance.cursor or appearance.cssCursor. |
overlayStyle | { appearance } | Changes overlay appearance and/or the real CSS cursor. |
overlayMove | { x1,y1,x2,y2,durationMs?,easing?,appearance? } | Animated move. |
overlayMoveTo | { selector, pad?, durationMs?, easing? } | Moves overlay to selector center. |
overlayMoveToWait | { selector, timeoutMs?, pollMs?, pad?, durationMs?, easing?, appearance? } | Waits for a selector, then moves the overlay; appearance may also be updated. |
overlayLabel | { text?, placement?, dx?, dy?, style?, labelStyle?, persist?, show? } | Shows or hides the label; supports placement, dx, dy, style/labelStyle, persist, and show. |
overlayHide | { destroy?, keepCursor? } | Hides or destroys overlay and clears the real CSS cursor unless keepCursor:true. |
domExtractBlock | { selector?, selectorList?, nth?, ascend?, root?, rootStrategy?, allowTags?, allowAttrs?, maxDepth?, maxNodes?, maxChars?, visibleOnly?, avoid?, preWait?, timeoutMs?, pollMs? } | Extracts a safe HTML/text block. |
Note: The JS helpers (like
RTO_DOM_actions.js) may add convenience wrappers to RTOForm, but the authoritative list is the action names above.
Common examples
Login pattern
const tabKey = "app";
await RTOForm.waitForSelector({ tabKey: tabKey, selector: "#email" }, { timeoutMs: 8000 });
await RTOForm.setValue({ tabKey: tabKey, selector: "#email", value: "user@example.com" });
// If the target is a password field, it may be blocked by design.
// Prefer manual login or a non-sensitive auth mechanism.
await RTOForm.setValue({ tabKey: tabKey, selector: "#password", value: "••••••••" });
await RTOForm.click({ tabKey: tabKey, selector: "button[type=submit]" });
await RTOForm.waitForSelector({ tabKey: tabKey, selector: "#dashboard" }, { timeoutMs: 15000 });
Read + write HTML
const tabKey = "app";
// Read HTML (property can be "outerHTML", "innerText", "textContent", "value", etc.)
const res = await RTOForm.getHtml({ tabKey: tabKey, selector: "#content", prop: "outerHTML" });
console.log("result:", res);
// Write HTML (sanitized: scripts/handlers/iframes removed)
await RTOForm.setInnerHtml({ tabKey: tabKey, selector: "#content", html: "Hello" });
Modern overlay examples
Use a PNG locator cursor, move it to a real target, then attach a styled label.
window.RTOForm.command({
action: "overlayCreate",
x: 120,
y: 120,
appearance: {
kind: "png",
png: {
src: "./assets/cursors/maps.png",
width: 42,
height: 42
},
offsetX: 0,
offsetY: 0,
opacity: 1,
rotateDeg: 0
}
}, { tabKey: "demo", timeoutMs: 5000 });
window.RTOForm.command({
action: "overlayLabel",
text: "Target area",
placement: "top",
dx: 0,
dy: -8,
persist: true,
style: {
fontSize: "14px",
fontWeight: "600",
padding: "10px 14px",
borderRadius: "14px",
background: "rgba(40,40,60,.95)",
color: "#fff",
boxShadow: "0 10px 28px rgba(0,0,0,.25)",
border: "1px solid rgba(255,255,255,.18)",
lineHeight: "1.35"
}
}, { tabKey: "demo", timeoutMs: 4000 });
window.RTOForm.command({
action: "overlayMoveToWait",
selector: "#searchBox",
durationMs: 700,
easing: "easeInOut",
timeoutMs: 5000
}, { tabKey: "demo", timeoutMs: 12000 });
Selector tips
- Prefer stable IDs:
#login,#submit. - Prefer semantic attributes:
[name=email],[data-test=submit],[data-testid]. - Avoid fragile selectors:
div:nth-child(3) > span. - If a selector fails, you will often see
ELEMENT_NOT_FOUNDorTIMEOUT. - If the element is inside an iframe, it will typically be unreachable (top-frame only).