One readable language across every target.
Search the Ruviolta 3.0.1 .ut (User Testing) language: browser automation, API requests and assertions, native Android controls, project data, reusable flows, streaming protocols and more.

Workspace and execution commands
ruviolta --version
ruviolta initruviolta run projects/example "@exampleDomain"
ruviolta run projects/api-example "@getPost"
ruviolta debug projects/api-example "@uiAndApi"
ruviolta run projects/example "@exampleDomain" --env production
ruviolta run projects/example "@exampleDomain" --open-report
ruviolta run projects/example "@exampleDomain" --no-reportRun/debug examples use the ruviolta executable. For a project-local npm installation, prefix the same command with npx unless the binary is already on PATH.
.ut (User Testing) runtime. Choose a tab to focus the command reference.Android setup & lifecycle 7 entries
Provision the platform runtime, manage the virtual or real Android session, install applications and inspect native controls.
ruviolta android initDownloads and verifies the matching Android support package and creates the Android example project.
ruviolta android initruviolta mobile start androidStarts the configured virtual or real Android session.
ruviolta mobile start androidruviolta mobile stop androidStops the owned Android session and restores temporary device settings.
ruviolta mobile stop androidruviolta mobile statusShows the current mobile runtime and connected-device status.
ruviolta mobile statusruviolta mobile app install android <apk-path>Installs an APK on the configured Android device.
ruviolta mobile app install android projects/android/demoData/Ruviolta-Demo-1.1.2.apkruviolta mobile app launch android <apk-path>Installs when needed and launches an Android APK.
ruviolta mobile app launch android path/to/application.apkruviolta mobile inspect androidPrints the currently inspectable native Android controls and selectors.
ruviolta mobile inspect androidStandalone native Android steps 14 entries
Each command is shown independently with the selector, occurrence, context and variable forms it actually supports.
waitFor(target[, qualifier][, timeout])Waits until a native target is available, scrolling through supported content when necessary.
contains[], symbol[] or a structured Android selector.nextTo[], before[] or after[].waitFor("Sign in")
waitFor(contains["signed in"])
waitFor("Open", 2)
waitFor(contains["student"], 2, 10000)
waitFor(symbol["U+F100"])
waitFor("A", nextTo["Class 7"])
waitFor("Save", before["Edit"])
waitFor(contains["student"], after["Title"])click(target[, qualifier])Activates a native control using exact, partial, repeated, contextual or symbol matching.
click("Sign in")
click(contains["sign"])
click("Open", 2)
click(symbol["U+F100"])
click("A", nextTo["Class 7"])
click("Save", before["Edit"])
click("Save", after["Preview"])
click(symbol["U+F100"], nextTo[contains["Georgi"]])input(target, value)Enters text into an exact native input target without clearing its existing value first.
input("Email address", loginEmail)
input("Password", loginPassword)replaceInput(target[, qualifier], value)Clears a native input safely, enters the replacement value and verifies the result.
replaceInput("First name", "Georgi")
replaceInput(contains["message"], "New text")
replaceInput(contains["message"], 2, "Second message")
replaceInput("Phone", nextTo[contains["Contact"]], phoneNumber)select(target, option)Opens a native selection control and chooses a full or unambiguous partial option match.
select("Country select", "Bulgaria")
select("Priority select", priority)upload(target, filePath)Stages a local file and completes the system picker on virtual or real Android devices.
.ut file, an absolute path or a variable containing either.upload("Choose a file", "../demoData/DemoData.pdf")
upload("Choose a file", attachmentPath)switch(target[, qualifier], ON|OFF)Sets a native switch idempotently and verifies the requested state.
switch("Notifications", ON)
switch(contains["notification"], OFF)
switch("Notifications", 2, ON)
switch("Notifications", nextTo[contains["Profile"]], OFF)checkbox(target[, qualifier], ON|OFF)Sets a native checkbox idempotently and verifies the requested state.
checkbox("Accept terms", ON)
checkbox(contains["terms"], OFF)
checkbox("Active", 2, ON)
checkbox("Active", after[contains["Profile"]], OFF)radio(target[, qualifier])Selects a native radio option only when necessary and verifies its checked state.
radio("High")
radio(contains["priority"])
radio("Yes", 2)
radio("Yes", before[contains["Advanced"]])longPress(target[, qualifier], seconds)Performs one continuous native press-and-hold gesture.
longPress("Card", 1.5)
longPress(contains["student"], 2)
longPress("Card", 2, 1.5)
longPress(symbol["U+F100"], nextTo[contains["Georgi"]], 2)dragAndDrop(source[, qualifier], destination[, qualifier])Drags one native target to another with optional source and destination qualifiers.
dragAndDrop("Student", "Archive")
dragAndDrop(contains["Georgi"], contains["Class 7"])
dragAndDrop("A", nextTo["Class 7"], "Selected")
dragAndDrop("Student", 2, "Archive", after["Completed"])scrollTo(target[, qualifier])Scrolls with bounded progress detection until the requested native target is reached.
scrollTo("Submit request")
scrollTo(contains["student"])
scrollTo(contains["student"], 2)
scrollTo(symbol["U+F100"])
scrollTo("A", nextTo["Class 7"])
scrollTo(contains["student"], after["Title"])swipe(direction)Performs a display-relative Android swipe in one supported direction.
swipe("up")
swipe("down")
swipe("left")
swipe("right")back()Dispatches the Android system Back action.
back()Android selector forms 7 entries
Selector forms are shown separately and can be used by the compatible standalone commands above or preserved by a waitFor() chain.
"Exact text"Matches normalized native hierarchy text exactly.
click("Sign in")contains["text"]Matches a normalized, case-insensitive part of the native text.
click(contains["sign"])target, occurrenceSelects one 1-based occurrence when several native targets match.
click("Open", 2)
scrollTo(contains["student"], 3)nextTo[anchor]Resolves a target in the nearest meaningful hierarchy context beside an anchor.
click("A", nextTo["Class 7"])
click("A", nextTo[contains["Class 7"]])before[anchor]Resolves a target before an exact or partial contextual anchor.
click("Save", before["Edit"])
radio("Yes", before[contains["Advanced"]])after[anchor]Resolves a target after an exact or partial contextual anchor.
click("Save", after["Preview"])
scrollTo(contains["student"], after[contains["Title"]])symbol["U+XXXX"]Matches the real Unicode code point exposed by an icon-font control.
click(symbol["U+F100"])
click(symbol["U+F100"], nextTo[contains["Georgi"]])Android waitFor() chain actions 9 entries
An Android chain begins with waitFor(), preserves its selector and qualifier, then performs exactly one freshly resolved target action.
waitFor().click()Waits for the target, resolves it again and clicks it.
waitFor("FORM").click()
waitFor(symbol["U+F100"], nextTo[contains["Georgi"]]).click()waitFor().input(value)Waits for a native input and enters the supplied value.
waitFor("Email address").input(loginEmail)waitFor().replaceInput(value)Waits for a native input, clears it and enters the replacement value.
waitFor("First name").replaceInput("Georgi")
waitFor("Phone", nextTo[contains["Contact"]]).replaceInput(phoneNumber)waitFor().clear()Waits for a native input and clears its current value.
waitFor("Search").clear()waitFor().select(option)Waits for a native selection control and chooses an option.
waitFor("Country select").select("Bulgaria")waitFor().longPress(seconds)Waits for the target and performs one continuous hold gesture.
waitFor("Gallery").longPress(1.5)waitFor().switch(ON|OFF)Waits for a switch and sets its state idempotently.
waitFor("Dark theme").switch(ON)waitFor().checkbox(ON|OFF)Waits for a checkbox and sets its state idempotently.
waitFor("Accept terms").checkbox(ON)waitFor().radio()Waits for a radio option and selects it only when necessary.
waitFor("High").radio()Language & data 13 entries
File structure, JavaScript expressions and local data helpers.
File Description: textDescribes the purpose of the current Ruviolta test file.
File Description: Login and authentication testsGlobal Variables:Starts the file-global variable section. Its declarations provide a fresh baseline to each concrete scenario invocation in this file and do not cross .ut file boundaries automatically.
Global Variables:
let baseUrl = "https://example.com"Global Variables: / Variables:Declares initialization variables. File globals provide a fresh baseline to scenarios in that file; scenario variables belong only to the current concrete scenario or Case invocation.
Variables:
let username = "John"Scenario: nameStarts a new test scenario.
Scenario: User logs in successfullylet variable = expressionInitializes a file/scenario variable inside its variable section or evaluates a chronological runtime step inside a scenario or Cleanup. Runtime let statements may create or update scenario-local values. Multiline expressions and await are supported.
let total = price * quantitylet user = { name: "John", active: true }let createdAt = new Date("2026-08-15T14:30:00Z")param(defaultExpression)Declares an explicitly bindable run() parameter slot at the source position of a let statement. The default expression is evaluated in the called scenario when no invocation value is supplied. param() is not a runtime function outside a let declaration.
let teacherName = param("John")let room = param(defaultRoom)script { ... }Runs a full asynchronous JavaScript block. Ruviolta variables, commands and file helpers are available inside it.
script {
await Promise.resolve()
console.log("Completed")
}readText(path, encoding?)Reads a text file relative to the current `.ut` file.
let message = readText("data/message.txt")readJson(path)Reads and parses a JSON file relative to the current `.ut` file.
let user = readJson("data/user.json")readCsv(path, options?)Reads a CSV file and returns an array of row objects. CSV field values are returned as strings.
let users = readCsv("data/users.csv")readBytes(path)Reads a file as a Node.js `Buffer`.
let bytes = readBytes("data/file.bin")env(name, fallback?)Returns an environment variable or an optional fallback value.
let apiUrl = env("API_URL", "https://example.com")await importJs(path)Imports a JavaScript module relative to the current `.ut` file and returns its exported members.
let helpers = await importJs("helpers/functions.js")let total = helpers.calculateTotal(25, 4) timeout. wait(milliseconds) remains a fixed delay.Navigation 5 entries
Page navigation and URL/title state.
visit(url)Navigates the active supported browser. Relative paths use the project UI base URL; JavaScript expressions are supported.
visit("https://example.com")visit(baseUrl)waitForUrl(expected, timeout?)Waits until the current URL exactly matches the expected absolute URL or project-relative path.
timeout.waitForUrl("/dashboard")waitForUrl("/dashboard", 10000)waitForUrlContains(expected, timeout?)Waits until the current URL contains the expected text.
timeout.waitForUrlContains("/students/")waitForUrlContains("/students/", 10000)waitForTitle(expected, timeout?)Waits until the page title exactly matches the expected text.
timeout.waitForTitle("Student profile")waitForTitle("Student profile", 5000)refresh()Reloads the current page and waits until it finishes loading.
refresh()Browser sessions & network 3 entries
Switch isolated declared windows and control scenario-scoped browser network behavior.
openWindow(number)Switches to a declared isolated browser window. Declare the number of windows in scenario Variables with let multiWindows = N.
Variables:
let multiWindows = 2
visit("https://example.com")
openWindow(2)
visit("https://example.org")
openWindow(1)mockNetwork(pattern, options)Registers a scenario-scoped browser network mock. Patterns support * and **; the first matching mock wins.
mockNetwork("**/api/profile", {
status: 200,
headers: { "content-type": "application/json" },
json: { id: 42, name: "Test User" }
})clearNetworkMocks()Removes the network mocks registered by the current scenario.
clearNetworkMocks()Waiting & state 16 entries
Explicit waits and state assertions.
waitFor(locator, timeout?)Waits until an element is found and visible. CSS selectors, XPath, variables, expressions, and locator-context chaining are supported.
timeout.waitFor("#username")waitFor("#username", 3000)waitFor(loginButton)waitForVisible(locator, timeout?)Readable alias of waitFor() that waits for a visible element and can provide locator context to a chained action.
timeout.waitForVisible("#search").clear().input(searchText)waitForVisible("#search", 5000).clear().input(searchText)waitForLink(target, text?, [occurrence]?, timeout?)Waits for a visible link-like element using exact normalized text or a CSS/XPath locator. Links include <a> elements and elements with role="link". Occurrence is 1-based and must precede timeout. The resolved semantic target can provide fresh locator context to a chained action.
waitForLink("Add").click()waitForLink("Add", [2], 3000)waitForLink("//a", "Add", [2], 5000).click()waitForButton(target, text?, [occurrence]?, timeout?)Waits for a visible button-like element using exact normalized text or a CSS/XPath locator. Buttons include <button>, button/submit/reset inputs, and elements with role="button". Occurrence is 1-based and must precede timeout. The resolved semantic target can provide fresh locator context to a chained action.
waitForButton("Save").click()waitForButton("Save", [2], 3000)waitForButton("button.action", "Save", [4], 3000).click()wait(milliseconds)Waits for the specified number of milliseconds before continuing the scenario.
wait(1000)waitForText(locator, text, timeout?)Retries until visible text contains the expected text using case-sensitive, whitespace-normalized matching.
timeout.waitForText("#status", "completed")waitForText("#status", "completed", 5000)waitUntilMissing(locator, timeout?)Waits until an element is removed from the DOM. Use waitForHidden() when the element should remain present but become invisible.
timeout.waitUntilMissing(".loading-spinner")waitUntilMissing(".loading-spinner", 5000)waitForEnabled(locator, timeout?)Waits until an element is visible and enabled, and can provide its locator to a chained action such as click().
timeout.waitForEnabled("#submit")waitForEnabled("#submit").click()waitForEnabled("#submit", 5000).click()waitForDisabled(locator, timeout?)Waits until an element becomes disabled through the native disabled state or aria-disabled="true".
timeout.waitForDisabled("#save")waitForDisabled("#save", 5000)waitForHidden(locator, timeout?)Waits until an element remains in the DOM but is no longer visible. Use waitUntilMissing() when the element should be removed.
timeout.waitForHidden(".loading-overlay")waitForHidden(".loading-overlay", 5000)waitForChecked(locator, timeout?)Waits until a checkbox, radio button or ARIA switch becomes checked without changing its state.
timeout.waitForChecked("#terms")waitForChecked("#terms", 5000)waitForUnchecked(locator, timeout?)Waits until a checkbox, radio button or ARIA switch becomes unchecked without changing its state.
timeout.waitForUnchecked("#newsletter")waitForUnchecked("#newsletter", 5000)waitForValue(locator, expectedValue, timeout?)Retries until the selected element's DOM value exactly matches the expected string value. String, number, and boolean expectations are converted deterministically to strings.
timeout.waitForValue("#email", expectedEmail)waitForValue("#email", expectedEmail, 5000)waitForAttribute(locator, attributeName, expectedValue, timeout?)Retries until a DOM attribute exactly matches. Use null to require the attribute to be missing; an empty string requires a present empty attribute.
timeout.waitForAttribute("#status", "data-state", "ready")waitForAttribute("#status", "data-state", "ready", 5000)waitForAttribute("#dialog", "hidden", null)waitForProperty(locator, propertyName, expectedValue, timeout?)Retries until a direct DOM property exactly matches with type-sensitive primitive or safe JSON-compatible structural comparison.
timeout.waitForProperty("#submit", "disabled", false)waitForProperty("#submit", "disabled", false, 5000)waitForCount(locator, expectedCount, timeout?)Retries until the exact number of visible CSS or XPath matches equals a non-negative integer, including zero.
timeout.waitForCount(".search-result", 3)waitForCount(".search-result", 3, 5000)waitForCount("//li[@role='option']", expectedCount)Elements & forms 21 entries
Clicking, typing, form controls and page scrolling.
click(locator)Waits for a usable visible element, then performs one real browser click without replaying the action.
click("#login")click(loginButton)hover(locator)Moves the real browser pointer over a visible element so hover menus, tooltips and mouseenter behavior can be tested.
hover("#profile-menu")clickByLabel(labelText, targetLocator)Finds the first visible exact label text, searches nearby containers for the supplied CSS or XPath target, and clicks the first visible match. XPath expressions are scoped to the label container.
clickByLabel("Students:", "//button[normalize-space()='Choose']")clickRepeated(locator, count)Waits for and clicks a repeating element the requested number of times, waiting for the page to change between clicks. Standalone usage requires locator and count. In a locator chain, clickRepeated(count) inherits the current target, while clickRepeated(locator, count) overrides it.
clickRepeated("//button[.='Save and continue']", 5)waitFor("#save").clickRepeated(3)waitForLink("Add").clickRepeated(5)waitForButton("Save").clickRepeated(5)waitForLink("Add").clickRepeated("#another-target", 5)clickLink(text)Clicks one visible link by exact or partial text, ignoring case and extra whitespace.
clickLink("read more")clickButton(text)Clicks one visible button by exact or partial text, ignoring case and extra whitespace.
clickButton("save")scrollTo(locator)Waits for a CSS or XPath element, scrolls it into the viewport, and verifies that it is visible after the layout settles.
scrollTo("#save-button")scrollTo("//footer")pageUP()Scrolls the current page to coordinates 0, 0 and verifies that the top of the page was reached.
pageUP()pageDown()Scrolls the current page to its bottom and verifies that the bottom boundary was reached.
pageDown()clear(locator)Clears a text field through user-like keyboard input and can provide its locator to a chained action.
clear("#username")clear(usernameField)clear("#username").input(userName)input(locator, value)Enters text through the browser keyboard lifecycle. Locators and values support variables and JavaScript expressions.
input("#username", "John")input(passwordField, password)replaceInput(locator, value)Clears the target field and enters a new value using normal browser input behavior. It can also inherit locator context in a command chain.
replaceInput("#name", "Georgi Todorov")waitForVisible(fieldLocator).replaceInput(userName)inputRepeated(locatorExpression, positions, values)Repeats the existing input() behavior once for every current position value. Normal Ruviolta expressions are evaluated first and every {{current}} placeholder is replaced with the current position value. An array third argument maps values one-to-one and must have the same length as positions. A scalar third argument reuses the same input value for every position. A one-element array remains positional and is not repeat mode. The command remains one Ruviolta step.
inputRepeated(
"//tr[@id='row-{{current}}-0']//input[contains(@class, 'weeks1')]",
[1, 2, 3, 8],
["18", "20", "22", "24"]
)inputRepeated(
"//tr[@id='row-{{current}}-0']//input",
[1, 2, 3],
"18"
)inputRepeated(
"#row-{{current}}-0 input.weeks1",
rows,
weeks
)inputByLabel(labelText, value)Finds an editable input or textarea associated with or positioned near the first visible exact label text, then enters the value without requiring a selector.
inputByLabel("Name", firstName)inputByLabel("Phone", "00882xxxxxx")upload(locator, filePath)Uploads a file through an `<input type="file">`. Relative paths are resolved from the current `.ut` file.
upload("#avatar", "data/photo.png")select(option) / select(locator, option)Selects an option by normalized visible text, partial visible text or exact value. CSS and XPath locators are supported.
select("important school year")select("//select[@name='country']", "Bulgaria")selectRepeated(locatorExpression, positions, values)Repeats the existing select() behavior once for every item in positions. Normal Ruviolta expressions are evaluated first and every {{current}} placeholder is replaced with the current position value. An array third argument maps values one-to-one and must have the same length as positions. A scalar third argument reuses the same value for every position. A one-element array remains positional and is not repeat mode. The command remains one Ruviolta step.
selectRepeated(
"//tr[@id='row-{{current}}-0']//select[contains(@class, 'courseSelect')]",
[1, 2, 3, 8],
["86", "26", "27", "125436"]
)selectRepeated(
"//tr[@id='row-{{current}}-0']//select",
[1, 2, 3],
"John"
)selectRepeated(
"#row-{{current}}-0 select.courseSelect",
rows,
courses
)checkSelectedText(locator, expectedText)Checks that the currently selected visible option text of a select element contains the expected text.
checkSelectedText("#class_profile_id", classProfile)checkSelectedText("//select[@id='class_profile_id']", "Students from: " + classLevel)check(locator)Ensures that a native or ARIA checkbox is checked. It clicks only when the checkbox is currently unchecked.
check("#terms")radio(locator)Selects a native or ARIA radio button only when it is not already selected, then verifies the selected state. Disabled radio buttons fail the step.
radio("input[name='role'][value='teacher']")uncheck(locator)Ensures that a native or ARIA checkbox is unchecked. It clicks only when the checkbox is currently checked.
uncheck("#newsletter")Keyboard & mouse 34 entries
Keyboard input and advanced mouse interactions.
doubleClick(locator)Performs a real double-click on a visible enabled element.
doubleClick("#document")rightClick(locator)Performs a real right-click on a visible enabled element.
rightClick("#row")sendKeys(locator, keys...)Focuses an element and sends keys or keyboard combinations in sequence.
sendKeys(usernameField, CTRL+A, BACKSPACE)sendKeys(passwordField, ENTER)dragAndDrop(sourceLocator, targetLocator)Drags the first visible element to the center of the second element using mouse events.
dragAndDrop("#card", "#done-column")CTRLThe Control modifier for `sendKeys()`.
sendKeys(field, CTRL+A)SHIFTThe Shift modifier for `sendKeys()`.
sendKeys(field, SHIFT+TAB)ALTThe Alt modifier for `sendKeys()`.
sendKeys(field, ALT+F4)METAThe system Meta modifier for `sendKeys()`.
sendKeys(field, META+A)ENTERSends the Enter key.
sendKeys(field, ENTER)TABSends the Tab key.
sendKeys(field, TAB)ESCAPESends the Escape key.
sendKeys(field, ESCAPE)BACKSPACESends the Backspace key.
sendKeys(field, BACKSPACE)DELETESends the Delete key.
sendKeys(field, DELETE)SPACESends the Space key.
sendKeys(field, SPACE)HOMEMoves the cursor to the beginning.
sendKeys(field, HOME)ENDMoves the cursor to the end.
sendKeys(field, END)PAGE_UPSends the Page Up key.
sendKeys(field, PAGE_UP)PAGE_DOWNSends the Page Down key.
sendKeys(field, PAGE_DOWN)ARROW_UPSends the Up Arrow key.
sendKeys(field, ARROW_UP)ARROW_DOWNSends the Down Arrow key.
sendKeys(field, ARROW_DOWN)ARROW_LEFTSends the Left Arrow key.
sendKeys(field, ARROW_LEFT)ARROW_RIGHTSends the Right Arrow key.
sendKeys(field, ARROW_RIGHT)F1Sends the F1 function key.
sendKeys(field, F1)F2Sends the F2 function key.
sendKeys(field, F2)F3Sends the F3 function key.
sendKeys(field, F3)F4Sends the F4 function key.
sendKeys(field, F4)F5Sends the F5 function key.
sendKeys(field, F5)F6Sends the F6 function key.
sendKeys(field, F6)F7Sends the F7 function key.
sendKeys(field, F7)F8Sends the F8 function key.
sendKeys(field, F8)F9Sends the F9 function key.
sendKeys(field, F9)F10Sends the F10 function key.
sendKeys(field, F10)F11Sends the F11 function key.
sendKeys(field, F11)F12Sends the F12 function key.
sendKeys(field, F12)Dialogs, cookies & toasts 6 entries
Native dialogs, consent banners and notifications.
waitForDialog(timeout?)Waits for a JavaScript dialog and must be followed immediately by dialog(accept), dialog(cancel) or dialog(dismiss).
timeout.waitForDialog()
dialog(accept)waitForDialog(5000)
dialog(accept)dialog(action, promptText?)Accepts or dismisses a JavaScript dialog. It can follow waitForDialog() or be used directly after the action that opens the dialog.
dialog(accept)dialog(accept, "Ruviolta")cookies(action, locator?)Accepts or rejects a cookie consent banner. Supply a locator for non-standard banners.
cookies(accept)cookies(reject, "#reject-cookies")waitToastMessage(text, timeout?)Waits for a visible toast or live notification containing the text. Matching is partial and case-insensitive.
timeout.waitToastMessage("successfully")waitToastMessage("successfully", 3000)closeToastMessage(text)Finds a toast by partial case-insensitive text and clicks its visible close control.
closeToastMessage("success")closeAllToasts()Waits 800 ms, finds visible toast notifications and tries to close all of them. It is a best-effort cleanup command and never fails the scenario when no toast exists or a toast cannot be closed.
closeAllToasts()Reusable flows 4 entries
Same-project and cross-project reusable scenarios.
run(reference) { positional, named: expression } -> resultRuns a tagged scenario or all scenarios from another .ut file in the same project or a sibling Ruviolta project. An optional invocation block binds explicit positional and named values to let declarations using param(defaultExpression). Positional values follow parameter source order; named values bind by name and override a positional value for the same slot. Values are evaluated at the run step, nested values are not inherited unless forwarded explicitly, and the optional -> result captures output(...) from the called flow. The legacy second-argument input object remains supported.
run("tests/auth.ut@login") {
email,
password
} -> authrun("tests/users.ut@create") {
"Alice",
role: requestedRole
} -> createdrun("tests/auth.ut@login", {
email,
password
}) -> authrun("shared-api/tests/create-user.ut@create", {
user
}) -> createdruviolta.accept(value, fallbackValue)Uses a variable supplied by run() when it exists, otherwise returns the fallback value.
let userName = ruviolta.accept(userName, "Georgi Todorov")Worker: nameDefines one explicit parallel worker. Workers execute concurrently; the steps and run() calls inside each worker stay strictly sequential and use an isolated runtime/browser session.
Worker: web
run("tests/login.ut@login")
run("tests/dashboard.ut@smoke")
Worker: api
run("projects/api-example/tests/api.ut@getPost")runRepeated(reference)[count]Runs the same reusable flow a fixed number of times. Use default parameters, one reusable dataset, or exactly one positional dataset per iteration.
runRepeated("tests/classDiary.ut@createClassDiary")[2]
{"11", "P"},
{"12", "A"}Cases, verification & lifecycle 4 entries
Data-driven scenarios, grouped assertions and deterministic cleanup.
Cases: table | readJson(path) | readCsv(path) | literal arrayOptionally expands one source scenario into independent case executions. Each table row or dataset object supplies case variables, and Cleanup runs once per case.
Cases:
| role | expectedStatus |
| admin | 200 |
| student | 403 |Cases: readJson("data/roles.json")Verify:Runs indented assertion steps in source order and reports all value mismatches in the group before failing the main flow.
Verify:
expectStatus(200)
expectSchema("$.user.id", "integer")
expectContainsAny("$.user.roles", ["admin", "teacher"])Cleanup:Runs scenario cleanup after the main flow even when a UI or API step fails. With Cases, cleanup runs once per case.
Cleanup:
api("DELETE", "/users/{id}", { path: { id: userId } })
expectStatus(204)output(value)Returns an explicit value from a called run() flow so the caller can capture it with -> result.
output({ id: responseBody.id, name: responseBody.name })API requests & authentication 3 entries
HTTP requests, OAuth 2.0 and polling.
api(method, path, options?)Sends one explicit HTTP request. Relative paths resolve against api.baseUrl and the normalized response becomes available to following steps.
api("GET", "/users/{id}", {
path: { id: userId },
query: { include: "roles" },
auth: { type: "bearer", token }
})oauth2(target, options)Acquires or supplies an OAuth 2.0 token and stores it in the target variable. Supports client credentials, refresh token, authorization code / PKCE, password and provided-token flows.
oauth2(token, { flow: "clientCredentials", tokenUrl: "/oauth/token", clientId, clientSecret })poll(method, path, options)Repeats an HTTP request until options.until matches or the polling timeout is reached.
poll("GET", "/jobs/{id}", { path: { id }, interval: 500, timeout: 10000, until: { path: "$.state", equals: "done" } })API assertions & capture 17 entries
Status, headers, cookies, JSON, schemas, response time and captured response data.
expectStatus(expected)Verifies the response status against one status code or an allowed list.
expectStatus(201)expectStatus([200, 201, 204])expectHeader(name, expected)Checks a response header using exact, regular-expression or predicate matching.
expectHeader("content-type", /json/)expectCookie(name, expected?)Verifies a response cookie by name and optional expected value.
expectCookie("session")expectJson(path?, expected, mode?)Checks JSON at a Ruviolta JSON path. Direct paths select one value; wildcard, recursive-property and safe array-filter paths select ordered collections. With one argument it checks the full response body.
expectJson("$.id", userId)expectJson("$.items[?(@.active == true)].id", [1, 3])expectJsonNotEqual(path, expected)Requires the selected JSON value to differ from the expected value.
expectJsonNotEqual("$.user.status", "disabled")expectExists(path)Requires a JSON path to exist. A present null value still counts as existing.
expectExists("$.user.email")expectMissing(path)Requires a JSON path to be absent.
expectMissing("$.user.legacyId")expectContains(path?, expected)Deeply checks that JSON (or response text) contains the expected value.
expectContains("$.roles", [{ name: "qa" }])expectNotContains(path, expected)Requires the selected JSON value not to contain the expected value.
expectNotContains("$.user.roles", "guest")expectContainsAny(path, expectedValues)Checks that an array contains at least one candidate from a non-empty expected-values array.
expectContainsAny("$.roles", ["admin", "owner"])expectContainsOnly(path, expectedValues)Checks an array as an order-independent, duplicate-aware collection and reports missing and unexpected values.
expectContainsOnly("$.roles", ["admin", "teacher"])expectCount(path, expectedCount)Checks the length of an array or wildcard, recursive-property, or filter collection selection.
expectCount("$.users", 3)expectEach(path, expected, mode?)Validates every value selected by a JSON path.
expectEach("$.users[*]", user => user.active === true)expectSchema(path?, schema)Validates JSON using readable Ruviolta schema descriptors.
expectSchema("$.user", {
id: "integer",
name: "string",
deletedAt: { type: "datetime", nullable: true }
})expectResponseTime(maximumMs)Fails when the previous HTTP request took longer than the supplied maximum.
expectResponseTime(1500)expectText(expected, mode?)Checks the raw response text using exact, contains or regular-expression matching.
expectText("success", "contains")captureJson(path) -> variableCaptures a JSON path result into normal scenario scope. Missing paths fail instead of becoming synthetic empty values.
captureJson("$.user.id") -> userIdGraphQL, SOAP, XML & realtime protocols 11 entries
XML/XPath, GraphQL, SOAP, WebSocket and Server-Sent Events.
expectXPath(xpath, expected?, options?)Safely evaluates XPath against the current XML response. Without expected, at least one selected node must exist. With expected, node string values or XPath scalar results use normal Ruviolta matching.
expectXPath("//student/id")expectXPath("//student/id", "42")expectXPath("//s:name", "Ada", { namespaces: { s: "urn:students" } })captureXPath(xpath, options?) -> variableSafely evaluates XPath against the current XML response and captures the selected string value, ordered value array, or XPath scalar into scenario scope.
captureXPath("//student/id") -> studentIdcaptureXPath("//s:id", { namespaces: { s: "urn:students" } }) -> studentIdgraphql(path, query, variables?, options?)Sends a GraphQL POST request while keeping the same response, assertion, report and debugger model as api().
graphql("/graphql", query, { id: userId })soap(path, envelope, options?)Sends a SOAP 1.1 or SOAP 1.2 request and exposes the response to normal status, text and XPath assertions.
soap("/soap", envelope, { soapAction: "GetUser" })websocket(name, url, options?)Opens a named WebSocket session. Several sessions can coexist.
websocket("feed", "/ws", { auth: { type: "bearer", token } })wsSend(name, value)Sends text, JSON or binary data through an open WebSocket session.
wsSend("feed", { action: "subscribe" })wsReceive(name, options?) -> messageWaits for one or multiple matching WebSocket messages. Non-matching queued messages remain available for later receives.
wsReceive("feed", { match: /update/, count: 2 }) -> updateswsClose(name, code?, reason?)Closes a named WebSocket session.
wsClose("feed")sse(name, url, options?)Opens a named Server-Sent Events session.
sse("events", "/events")sseReceive(name, options?) -> eventWaits for one or multiple matching SSE events and optionally captures them. Parsed JSON is available as event.json.
sseReceive("events", { match: { event: "status" }, count: 2 }) -> eventssseClose(name)Closes a named SSE session.
sseClose("events") response, responseStatus, responseHeaders, responseBody, responseText, responseTime and request in following steps and JavaScript expressions.