Appearance
Using JavaScript in UI-licious Tests
UI-licious test scripts are executed in a JavaScript sandbox.
Unlike other low-code, keyword-driven frameworks that introduce a custom DSL, UI-licious intentionally runs tests as JavaScript. This design gives developers the flexibility to write custom logic using a familiar language, while still benefiting from the simplicity of the UI-licious API. As a result, you can use standard JavaScript syntax, create reusable functions, and write data-driven tests without being constrained by the framework.
WARNING
Because tests are executed in a sandbox, you cannot install external libraries or use the import or export keywords. UI-licious provides the TEST.run function for running logic from another file (see below).
Variables, loops, and conditionals in practice
JavaScript is commonly used in UI-licious tests to:
- store and manipulate test data using variables
- branch test flows using conditionals
- iterate through datasets for data-driven testing
Here's an example:
js
// load products from csv
var products = TEST.loadDataFromCsv("data/products.csv", { headers: "row" })
// iterate products to search and add the product to the cart
products.forEach((p) => {
I.fill("Search", p.name)
I.pressEnter()
if (I.see$(p.name)) {
I.click("Add to cart")
} else {
TEST.log.fail("Product '" + p.name + "' is not found")
}
})Using functions to reuse logic
When a sequence of steps is used repeatedly, a common pattern is to extract it into a reusable function:
js
// this is a helper function to search for a product
// and then add it to cart if it exists
function searchAndAddToCartIfExists(productName){
I.fill("Search", productName)
I.pressEnter()
if (I.see$(productName)) {
I.click("Add to cart")
}
}
products.forEach((p) => searchAndAddToCartIfExists(p.name))This keeps tests readable and easy to maintain.
Reusing logic with TEST.run
Although the import and export keywords are not supported, UI-licious provides TEST.run() and TEST.runOnce() for executing other test files. This is commonly used for shared setup logic or reusable flows such as login.
js
// load utility functions
TEST.runOnce("helpers/date_utils")
// start of test case
TEST.run("flows/login")
I.see("Dashboard")This allows larger test suites to be composed from smaller, focused scripts without relying on external libraries.
For a deeper look at structuring reusable flows and composing larger test suites, see the guide on Reusing and Composing Tests.