Getting started

Prerequisites

Sakuli is built and tested against the current LTS version of Node.js. In order to be able to run Sakuli on your system, we will assume that you have a Node v10.15.3 (lts/dubnium) installed on it.

To install Node on your system, you can either go to the Node website or you can use tools like Node Version Manager, a utility to manage various Node versions on a per-user basis. In general, a per-user installation is the preferred way since it runs in an unprivileged mode.

Initialization

This guide will get you started with writing Sakuli tests from scratch. To follow this tutorial, you should create a new NPM project in an empty folder.

For this guide, we will assume that our working directory is /tmp/sakuli_starter on a *nix system, or %Temp%\sakuli_starter on a Windows machine.

To create a new, empty project, first run:

npm init

This interactive prompt will ask you for some metadata regarding your project. You can either modify these fields to your needs or just accept the defaults.

Once completed, you should see a short summary similar to the following snippet:

About to write to /tmp/sakuli_starter/package.json:

{
  "name": "sakuli_starter",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this OK? (yes)

The empty project has been initialized after confirming the prompt.

Installation

The following steps are required to set up Sakuli to work with multiple browsers. Once the initial setup is done, we will dive right into our first test.

WebDriver Installation

Sakuli utilizes the WebDriver protocol to remote control browsers during test execution. In addition to the browser itself, you need to install the corresponding WebDriver as well. Several wrapper packages can be found on npmjs.com, which allow the installation of the required binaries via npm.

Since some users encountered issues with geckodriver on Firefox, we recommend using chromedriver for now. We are working on fixes and workarounds for geckodriver.

Therefore, Chrome is the preferred browser for running Sakuli tests at the moment. A suitable WebDriver can be installed via:

npm i chromedriver

or

yarn add chromedriver

There are also WebDriver packages for IE and Edge. macOS already ships a WebDriver for Safari, so there is no need to install an additional package.

Attention: Be careful to install the correct version of a WebDriver package according to the installed browser version. To install e.g. ChromeDriver for Chrome 73 you have to install:

npm i chromedriver@73.0.0

Sakuli is not limited to work with only a single browser. When installing multiple WebDriver packages, you can easily switch between different browsers.

Regarding Windows Users: You will have to manually add the respective WebDriver location to your system PATH, otherwise Sakuli will not be able to find and use it. Once you installed a WebDriver package via NPM, you will be prompted with its installation path, so you can easily add it to your %PATH% variable.

Sample path:

%USERPROFILE%\\AppData\\Roaming\\npm\\node_modules\\chromedriver\\lib\\chromedriver\\

3rd-party dependencies

One of Sakuli’s core components, nut.js, requires OpenCV. Sakuli ships a pre-built version of OpenCV. Nonetheless, the installation still requires some 3rd-party dependencies.

Windows

In order to install and run Sakuli on Windows you need two additional tools: Python 2 and the Windows Build Tools.

To avoid eventual installation problems for Windows users we recommend to first install Python 2 on your system separately by downloading the required version from the official web page. Afterwards you can install the Windows Build Tools manually or via NPM using:

npm install --global windows-build-tools

or

yarn global add windows-build-tools

In case of errors while installing the Windows Build Tools package via npm, please make sure that the PowerShell is available on your system PATH. Additionally, you should install the Windows Build Tools by using the PowerShell in administrative mode.
See this issue for further reference.

macOS

On macOS, Xcode command line tools are required. You can install them by running:

xcode-select --install

Linux

Depending on your distribution, Linux setups may differ.

In general, Sakuli requires:

  • Python 2
  • g++
  • make
  • libXtst
  • libPng

Installation on *buntu:

sudo apt-get install build-essential python libxtst-dev libpng++-dev

The installation process is an open issue and will be improved in the near future, so using Sakuli will become even more enjoyable!

Sakuli Installation

We will now install Sakuli in our newly created project by running:

npm i @sakuli/cli

or

yarn add @sakuli/cli

This will install Sakuli and its required dependencies.

Reference

Setup your first test

Since we wanted to keep Sakuli mostly compatible to v1, the file layout looks basically the same for testsuites.

Each testsuite is located in its own particular folder. Generally, a testsuite represents the system you want to test. Therefore, you need to create that folder in your project root (where the package.json file is located):

mkdir my-sut

To describe the testsuite and its testcases, two additional files are needed: testsuite.properties and testsuite.suite. These files are required for backwards compatibility (they might not be necessary in the future but will at least be supported). These files should be added to the my-sut folder:

cd my-sut
echo > testsuite.suite 
echo > testsuite.properties

We can add the following contents to testsuite.properties:

echo testsuite.id=my-sut > testsuite.properties

This is the minimum configuration for using Sakuli. The .properties file adds some metadata needed by the Sakuli-Runtime and can be changed to configure other things like forwarders or the default browser for the execution.

The testsuite.suite file tells Sakuli which testcases are running. The format is:

<FOLDER-NAME>/<FILE-NAME>.js <START_URL>

The actual testcase file must be placed inside a folder (this is due to the format forced by Sahi in Sakuli v1). The start-url also needs to be added but has no effect in v2+.

With this in mind, we can add a testcase file:

mkdir my-testcase
echo > my-testcase/testcase.js

And add the following information to the testsuite.suite file:

echo my-testcase/testcase.js https://sakuli.io > testsuite.suite

After the setup you can add the actual testcode to my-testcase/testcase.js:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
(async () => {  // 1
    const testCase = new TestCase(); // 2
    try {
        // actual testcode goes here
    } catch (e) {
        await testCase.handleException(e); // 3
    } finally {
        await testCase.saveResult(); // 4
    }
})().then(done); // 5

Let us examine this piece of code:

  1. The whole test is wrapped in an async immediate invoked function. It allows us to use the async/await syntax of ES6. Since Sakuli makes heavy use of async operations, it makes your code more readable.
  2. To provide Sakuli information about our actual testcase, we create a TestCase object, which handles the execution of a testcase.
  3. If any error occurs during testing, it will be redirected to the TestCase object. It triggers Sakuli’s internal error handling e.g. taking a screenshot of the actual failed test execution.
  4. Regardless of a failed or passed test execution, Sakuli saves all results. This is more like a legacy artifact and will be removed in the future.
  5. When the async code within the main function (see 1.) is completed, a callback passed to the then function is invoked. done is a global function, which is injected by Sakuli and which tells the engine that the test execution is over (in theory you could call this function done() but the syntax above is recommended).

Write your first Test

Let us write a simple test using the Sakuli.io homepage as test subject. This test will verify if our “Getting Started” guide that you are reading at this very moment is still accessible.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
(async () => {
    const testCase = new TestCase();
    try {
        await _navigateTo("https://sakuli.io");                  // 1
        testCase.endOfStep("Open Landing Page", 5, 10);          // 2
        await _click(_link("Getting started"));                  // 3
        testCase.endOfStep("Navigate to Getting Started", 3, 5);
        await _highlight(_code("npm init"));                     // 4
        testCase.endOfStep("Find npm init code sample");
    } catch (e) {
        await testCase.handleException(e);
    } finally {
        await testCase.saveResult();
    }
})().then(done);
  1. Since we are dealing with a web test, the first thing we want to do is to _navigateTo our target page. Instead of manually setting up the correct WebDriver instance, we just have to provide a target URL. Sakuli will take care of the rest for us. await indicates that we are patiently waiting for our page to load before we continue with our next testing step.
  2. Once our initial page load has been completed, it is of our great interest to know how long it took to render. When it comes to runtime, Sakuli does not only measure the execution time of testcases, but also allows to split a single testcase into several logical steps. This way it becomes possible to accurately measure the runtime of certain processes like e.g. login, shopping cart, checkout and so on. By calling testCase.endOfStep("Open Landing Page", 5, 10);, we are ending our first step, the initial page load. Additionally, it is also possible to specify warning and critical thresholds for each step. Whenever a step exceeds one of these values, the result will change from OK to WARNING or CRITICAL.
  3. With Sakuli it becomes very easy to interact with web elements. In our current example, we want to _click a _link which is identified by some given text. Once again, we do not have to take care of many details, as Sakuli will do most of the heavy lifting for us. We are just passing the link text to Sakuli, which will search for our desired element using multiple identifiers. This way we do not have to worry about using an ID, a CSS selector or something else to identify our element. As we have already seen in our first test action, await will wait until the test action has been completed.
  4. In some cases, it is really helpful to visually verify test execution. Sakuli comes with a built-in _highlight function, which will highlight an element with a bright red border. Although being useful, _highlight should be used carefully since it will increase the overall testing runtime.

Execute your first test

Since Sakuli 2 is built with Node, there are at least two different ways to execute a Sakuli test. We will take a look at each one of them. Organizing tests as NPM projects makes it easier for you to distribute testcode. Everything required to execute the test is described in a project config, so tests should be ready to use after running npm install inside a project. 👍

npx

Because of the way we have set up and configured our project in this guide, Sakuli is only available to this particular project. npx is a really handy tool, which allows us to execute our Sakuli CLI directly from the command line, even though we did not add it to the system PATH.

In order to run our first test, we just have to execute npx sakuli run my-sut inside our project folder (e.g. /tmp/sakuli_starter on *nix). By default, Sakuli will pick up the browser configured in the testsuite.properties file, but with npx it is possible to change the browser on the fly: Successful Sakuli test execution

npx sakuli run my-sut --browser chrome
This command will execute our test in Chrome.

Regardless of the browser choice, as long as our site did not slow down, you should see a successful test result, similar to the image on the right. The advantage of running your tests with npx is the flexibility to easily customize your test runs without having to edit files.

npm test

As mentioned earlier, we installed Sakuli locally into our test project. An alternative way to execute Sakuli tests are npm scripts.

In our project folder we can find a file named package.json, the central configuration file for NPM projects. This file contains a section called scripts, including a collection of scripts that belong to this package and that can be executed via NPM.

A default project contains a dummy script to execute tests, similar to the following snippet:

"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1"
},

The test script is the perfect place for us to execute our Sakuli test:

"scripts": {
  "test": "sakuli run my-sut --browser chrome"
},

To run the test, just execute

npm test
inside your project folder.

Many modern IDEs support npm scripts, so it is possible to trigger test execution directly from within your IDE!

Global installation

If you do not want to create separate NPM projects for your testsuites, it is also possible to install Sakuli on a global scale. When installed with the additional -g flag, Sakuli will be installed and added to your system PATH (Windows users still have to add it manually sometimes):

npm i -g @sakuli/cli

Once the installation has been completed, you can run your Sakuli tests from your command line by simply executing:

sakuli run $PATH_TO_TESTSUITE

Attention: Installing packages globally on a system wide installation of Node via sudo is considered a bad practice and might run into permission problems. Working with per-user installations is recommended!

Congratulations!

You wrote and executed your first Sakuli test! May there be many more to come!

If you want to learn more about native test actions, head over to the testing section!