Scripting and tests Pro / Enterprise
With the scripting feature of Kreya, you can define JavaScript code that runs when an operation is invoked. Among other things, it allows you to create tests and view the results of them.
Defining scripts
Scripts can be defined in the Script tab. The script will run when the operation is sent. Note that the script editor supports autocompletion, simply press Ctrl+Space to bring it up.
As you can see in the screenshot, a global kreya
object is provided. It currently defines two functions:
Function | Description | Arguments |
---|---|---|
trace(msg) | Use this function to log messages to the Trace tab. |
|
test(name, action) | Use this function to define tests. |
|
sleep(millisecondsTimeout) | Use this function to sleep for an certain length of time. |
|
In addition, Kreya also includes the chai module for defining tests in JavaScript.
Environment
You may want to access the current Kreya environment in a script.
This is available through the kreya.environment.active
object.
Property | Description |
---|---|
content: any | Contains the merged content of the active environment. |
id: string | A unique id of the environment. |
name: string | The name of the environment. |
User variables
Sometimes, you may need to share data between different operations. For example, if you have a process where you create an entity → update the entity → delete the entity, changing the entity ID manually each time becomes annoying. It would be much easier if you could temporarily store the ID of the created entity and reference it from the other two operations. For such use cases, user variables are the way to go.
The feature is available through the kreya.variables
object.
Function | Description | Arguments |
---|---|---|
set(key, value) | Sets a variable. |
|
get(key) | Gets the value of a variable. |
|
has(key) | Checks whether the specified variable exists. |
|
keys() | Returns the keys of all stored variables. | |
delete(key) | Deletes the specified variable. |
|
User variables can also be referenced via templating, for example {{ vars.my_variable }}
.
gRPC specific hooks
To write scripts and tests for gRPC, use the built-in kreyaGrpc
object. It currently provides two functions:
Function | Description | Callback object properties |
---|---|---|
onResponse(callback) | Use this function to register a callback which will be called every time a response arrives. |
|
onCallCompleted(callback) | Use this function to register a callback which will be called when the gRPC call completes. |
|
gRPC example
import { expect } from 'chai';
let names = [];
kreyaGrpc.onResponse(msg => {
kreya.test('Size should be ok', () => expect(msg.size).to.be.gt(10));
kreya.test('Greeting should start with Hello', () => expect(msg.content.greeting.startsWith('Hello')).to.be.true);
// Store all received names to use them when the gRPC call completes
names.push(msg.content.greeting.substr('Hello '.length));
});
kreyaGrpc.onCallCompleted(call => {
kreya.test('Status should be ok', () => expect(call.status.code).to.equal(0));
kreya.trace(`Got ${call.responseCount} names: ${names.join(', ')}`);
});
REST specific hooks
To write scripts and tests for REST, use the built-in kreyaRest
object. It currently provides one function:
Function | Description | Callback object properties |
---|---|---|
onCallCompleted(callback) | Use this function to register a callback which will be called when the REST call completes. |
|
onStreamEventReceived(callback) | Use this function to register a callback which will be called when a REST streamed event is received. |
|
* The response
object contains the following properties:
size
: The response size in bytescontentType
: The content type, read from the Content-Type HTTP headercontent
: The deserialized response content as a JavaScript objectrawContentText
: The response content as textrawContentBytes
: The response content as anUint8Array
Accessing the content
, rawContentText
or rawContentBytes
will throw an exception if the response size is greater than 10 MiB.
Accessing the content
will throw if the response content is not valid JSON or YAML.
REST example
import { expect } from 'chai';
kreyaRest.onCallCompleted(call => {
kreya.trace('The REST call completed.');
kreya.test('Status code', () => expect(call.status.code).to.equal(200));
kreya.test('status is success', () => expect(call.status.isSuccess).to.be.true);
kreya.test('Content type', () => expect(call.response.contentType).to.eq('application/json'));
const curlyBraceCharCode = '{'.charCodeAt(0);
kreya.test('Byte content first entry should be a curly brace', () => expect(call.response.rawContentBytes[0]).to.eq(curlyBraceCharCode));
kreya.test('Text content first char should be a curly brace', () => expect(call.response.rawContentText[0]).to.eq('{'));
kreya.test('Deserialized number should equal', () => expect(call.response.content.myInt).to.eq(26));
});
Viewing test results
The test results show up in the Tests tab. It will automatically show how many of the tests passed in the tab header. Should a test fail, Kreya will display the reason of the failure.
Sharing code
A typical scenario is to share test code among multiple operations.
This is where importing external modules comes in handy.
As an example, place a file named shared.js
in the Kreya project directory with the following content:
import { expect } from 'chai';
export function init() {
kreya.trace('hello from shared file');
}
export function addTestForSuccessfulResponse() {
kreyaRest.onCallCompleted(call => {
kreya.test('status is success', () => expect(call.status.isSuccess).to.be.true);
kreya.test('Status code', () => expect(call.status.code).to.equal(200));
});
}
Then, in the Script tab of a REST operation, we can import these shared functions:
import { init, addTestForSuccessfulResponse } from 'shared.js';
init();
addTestForSuccessfulResponse();
Importing external modules
While Kreya bundles the chai module, that may not be enough for some use cases. That is why importing external modules is also possible. Currently, only external ESM modules are supported. You may import external modules directly via URL or as local dependencies.
// Bundled with Kreya
import { expect } from 'chai';
// Imported directly from an URL
import { snakeCase } from 'https://esm.sh/change-case';
const snakeCased = snakeCase('my message');
kreya.test('Snake case', () => expect(snakeCased).to.eq('my_message'));
// Use a local module. Kreya searches in the project directory and parent directories.
// Either the module is declared in a package.json file (the module must be installed, Kreya does not perform a package restore)
// or the file is directly available as '{module-name}.js` or `{module-name}/index.js`
import { formatDistance } from 'date-fns';
const dayDistance = formatDistance(new Date(2020, 1, 1), new Date(2020, 1, 3), {
addSuffix: true,
});
kreya.test('Day distance', () => expect(dayDistance).to.eq('2 days ago'));