Anatomy of a Project

This guide assumes that you have finished the “Getting started” tutorial or that you are experienced with Sakuli v1.

Most of the complexity and conventions are due to the backwards compatibility to v1, which requires a specific folder and file structure for various reasons (the biggest is Sahi). Sakuli offers now various ways to reduce this complexity dramatically. These features will eventually become part of upcoming releases.

Setup and configuration

The minimum setup for a Sakuli project looks like this:

  • your-sakuli-project Home folder of the project
    • testsuite-a Home folder of a testsuite
      • _logs An automatically generated folder for error screenshots and sakuli.log
        • _screenshots Folder for error screenshots
        • sakuli.log Logs of Sakuli execution
      • testcase Home of the testcase
        • .check.js.steps.cache An automatically generated cache file
        • testcase.js The actual testcase
      • package.json (optional) Defines test script for container usage
      • testsuite.suite Defines which testcases belong to the testsuite
      • Configuration for the testsuite (overrides configuration from ‘../’)
    • package.json All dependencies and setups for Node.js
    • (optional) Configuration for all testsuites

This file layout also represents the logical structure of Sakuli, which consists of a testsuite with one or more testcase(s). Sakuli’s run command takes the path to a testsuite folder and runs all testcases defined in testsuite.suite of the given folder.


The folder _logs is created automatically when Sakuli starts the first execution of a test suite. To change the path of the created folder _logs you can use sakuli.log.folder. See Configuring Tests for more information.


Sakuli stores all error screenshots in this folder, which can be configured with these properties:

  • sakuli.screenshot.onError
  • sakuli.screenshot.dir

See Configuring Tests for more information.


Sakuli logs all information about the test execution in this file. To configure the log level, set log.level property in or accordingly.

.steps.cache file

The file ‘steps.cache’ is created after the first successful execution. It contains the step names of a test case (defined with testcase.endOfStep()). With the correct .steps.cache file Sakuli can omit the last step Finished step UNNAMED with state Ok..


This file is a relic from Sahi where you define testcases and their respective start-urls. It has a simple format:


<CASE-PATH> is a path within the testsuite file, which has to contain the file <CASE_FILE>. The <START-URL> is no longer used by Sakuli (but required to fulfil the file format). The format also supports comments (// at the beginning of a line). Testcases can be activated or deactivated by using comments.

The configured start-url is omitted to force test authors to write explicit navigation to the url for testcases using _navigateTo.

Properties Files

Each testsuite requires a file with at least one entry:

It “inherits” its values from ../ (which also means that the same property from becomes overridden).

Property files are a common way to store configuration in Java, the former runtime for Sakuli. It is a simple key-value format (<KEY>=<VALUE>) where every line defines a key-value pair. To organize the keys, it is a common - but not required - practice to separate names by dots (similar to Java namespaces).

There are several predefined properties that can be configured to influence the behavior of Sakuli (* indicates a required property):

Property Type: Default Comment / Example String*: / Name of the suite shown in the output and used by the forwarder
testsuite.browser String: ‘firefox’ Browser which is started by the WebDriver (it can be overridden by the --browser command line argument)

You can also define own properties and use them in your testcases. Just put your custom property key with the corresponding value in one of the .property files and into your testcase. You can retrieve the values with help of the Environment Class:

// omitting boilerplate 
// assuming you have added 
// in one of the property files
const env = new Environment();
await _setValue(_textbox('username'), env.getProperty(''));