Web, API and Android targets stay intentional.
Each project owns the settings it needs inside config/ruviolta.config.mjs: browser and API targets for Web/API projects, or a virtual or real device profile for Android projects.

Core UI + API configuration
export default {
baseUrl: "https://app.example.com/",
api: {
baseUrl: "https://api.example.com/",
timeout: 30000,
headers: {
Accept: "application/json",
},
followRedirects: true,
maxRedirects: 10,
reportBodyLimit: 12000,
secretNames: ["token", "clientSecret"],
tls: {
rejectUnauthorized: true,
},
},
browser: {
name: "chrome",
headless: false,
executablePath: null,
arguments: [],
reuseSession: false,
consoleLog: false,
viewport: {
maximized: true,
width: 1440,
height: 900,
},
},
timeout: 10000,
screenshotOnFail: true,
debugger: {
dock: "bottom",
compact: false,
window: {
width: 500,
height: 620,
compactWidth: 390,
},
},
login: {
enabled: false,
flow: "tests/login/login.ut@login",
},
reports: {
enabled: true,
openAfterRun: false,
videoOnFail: false,
},
security: {
restrictFileHelpersToProject: true,
allowJsImports: true,
allowedEnvironmentVariables: null,
},
};One configuration for virtual or real devices
export default {
android: {
device: {
type: "virtual", // or "real"
// serial: "device-serial",
},
toolbar: "hide",
softKeyboard: "hidden",
lifecycle: {
autoStart: true,
autoStop: true,
},
application: {
autoOpen: true,
name: "Ruviolta Demo",
packageId: "com.ruviolta.demo",
apkPath: "../demoData/Ruviolta-Demo-1.1.2.apk",
},
display: {
width: 432,
height: 768,
density: 440,
},
window: {
heightPercent: 85,
},
},
};Configuration-driven device choice
Switch between the managed virtual device and a connected real device without creating a second product project. An optional serial selects one device when several are connected.
softKeyboard: "hidden" suppresses the on-screen keyboard only during the Ruviolta session and restores the previous device behavior afterward. Omit it or use "show" for the device default.
baseUrl is UI. api.baseUrl is API.
Browser target
baseUrl is opened when the first browser command is reached. Later visit() calls resolve against it unless they use an absolute URL.
API target
api.baseUrl resolves relative api(), graphql(), soap(), polling, WebSocket and SSE URLs.
API-only
An API-only project may omit baseUrl. Ruviolta does not launch a browser until a browser command actually needs one.
Run one reusable login flow before the selected scenarios
login: {
enabled: true,
flow: "tests/login/login.ut@login",
},Configured once, reused automatically
When login.enabled is true, Ruviolta executes the configured flow once before the requested top-level scenarios, for both normal runs and Stepflow debugging.
The flow uses normal run() reference rules, may contain nested reusable flows, and prepares a browser only if the login itself reaches UI steps. The generated 3.0.1 projects include tests/login/login.ut with automatic login disabled until you adapt the template. In an explicit Worker: runner, each Worker owns its own login state: the target project login runs once when that Worker first enters the project, while later same-project run() calls reuse that Worker state.
Reuse sessions, capture console failures and keep Workers isolated
browser.reuseSession
Default false keeps separate top-level files isolated. Set it to true when separate top-level runs in the same project should intentionally reuse the prepared browser session.
browser.consoleLog
When enabled, failed scenarios append browser console evidence to <project>/logs/browser-console.log without adding console noise to the HTML report.
Worker isolation
Each explicit Worker owns its runtime, browser, variables and login state. Workers run concurrently while the steps inside one Worker remain sequential.
Switch UI and API targets together
export default {
environment: "staging",
environments: {
local: {
baseUrl: "http://localhost:3000/",
api: {
baseUrl: "http://localhost:8080/",
},
},
staging: {
baseUrl: "https://staging.example.com/",
api: {
baseUrl: "https://api-staging.example.com/",
},
},
production: {
baseUrl: "https://www.example.com/",
api: {
baseUrl: "https://api.example.com/",
},
},
},
};Temporarily override the active environment:
ruviolta run projects/example "@exampleDomain" --env production baseUrl and environments in the same project. Ruviolta rejects ambiguous configuration.Request behavior stays project-local
api: {
baseUrl: "https://api.example.com/",
timeout: 30000,
headers: {
Accept: "application/json",
},
cookieJar: true,
followRedirects: true,
maxRedirects: 10,
reportBodyLimit: 12000,
secretNames: ["token", "apiKey"],
tls: {
rejectUnauthorized: true,
},
}Per-request overrides
An individual api() call can override timeout, redirects, proxy, TLS, auth, cookies, headers, body and signing settings without changing the project defaults.
Sensitive names are redacted from terminal output, Stepflow details and HTML/JSON reports.
Visible, fixed-size or headless
Maximized
headless: false and maximized: true. The initial UI target is ready and maximized before the first browser step.
Fixed size
Set maximized: false and use the configured width and height for a deterministic visible viewport.
Headless
Set headless: true. Debug sessions temporarily use a visible browser when UI steps are reached.
Chrome, Edge or Firefox
| Browser | Configuration | Protocol |
|---|---|---|
| Google Chrome | name: "chrome" | Chrome DevTools Protocol |
| Microsoft Edge | name: "edge" | Chrome DevTools Protocol |
| Mozilla Firefox | name: "firefox" | WebDriver BiDi |
browser: {
name: "chrome",
executablePath: null,
arguments: ["--disable-notifications"],
}