Webhooks

Webhooks are HTTP-protocol based callbacks which enable you to react on changes in your Testlab project. Webhooks can be used as a one-way API to integrate your own system to Testlab.

How it works

Webhooks

Testlab implements webhooks as a channel in its notice schemes. Notice schemes are sets of rules which define which events in specific assets generate notifications to different channels such as e-mail, Slack or in this case, custom webhooks. For example, in Testlab, you can specify a notice scheme rule which fires a notification when an issue is resolved (= issue’s status is set as resolved). When the rule is tied to a webhook endpoint, a JSON encapsulated message is sent as an HTTP-POST to the endpoint specified.

 

How to get started

When a webhook notification is configured to Testlab, Testlab will make a call to an interface you have set up. You have to have an HTTP based endpoint set up where to point the notice scheme rules to. See below for simple examples of endpoints in different languages.

 

Set up notification scheme rules in Testlab

Log in to your Testlab and from the “Testlab” menu, choose “Manage notice schemes…”. If you already have a notice scheme set up and in use in your project, you can choose it and continue on. If not, create a new notice scheme:

  1. If you wish to use e-mail notifications too, choose a fitting scheme from the list of templates shown (for example, Assignees scheme). If not, choose the “Blank scheme” which has no rules at all.
  2. Click the copy button at the bottom left of the window, give the new scheme a name (for example “My webhooks”) and a description and check it as “Active”. Click the “Save” button.
  3. Select the “Webhooks” tab and enter the needed rules for assets you wish to send messages about. For example, if you wish to get HTTP callbacks every time an issue is resolved, enter the rule as follows:
    webhooks_rules
    Make sure to enter the address of your HTTP endpoint to the Destination URL for all the rules.
  4. Save the notice scheme rules by clicking the “Save” button.
  5. As the notice schemes are global in your Testlab, you must assign the (new) scheme to a project for it to take effect. Select “Manage projects…” from the “Testlab” menu, choose the project you wish to integrate with your endpoint using the new notice scheme and select the scheme for it and save changes.

 

The integration at Testlab side is now set up. Now, when you make changes to assets in your Testlab project you set up, the endpoints you defined should get HTTP/POST calls with JSON encapsulated payload.

 

JSON payload

This section documents the JSON format the events get delivered in.

The JSON is encoded with the following contract:

  • All dates are delivered as Epoch timestamps with milliseconds (For example 1442564045407 should be interpreted as Fri, 18 Sep 2015 08:14:05:407 GMT)
  • Description fields for assets are encoded in basic HTML
  • All fields with configurable option values are represented by the key value of the current option value set. The table below lists the default values provided by Testlab out of the box. If you customize the options for these fields, the customized values and their corresponding key values must be taken into account.

 

WebhookEvent

When webhook events are posted the payloads get delivered as WebhookEvents. Each event includes some common fields and in addition, the asset the event relates to.

Property Type Description
projectId long the unique primary key of the project the event relates to
project string prefix/identifier of the project the event relates to
event string the event, one of

  • CREATED: new asset was created
  • UPDATED: asset was updated
  • COMMENTED: asset was commented on
  • ASSIGNED: asset was updated and assigned to new assignee
  • TOSTATUS: asset was updated and moved to a new status
defect defect issue the event relates to if any
testCase testCase test case the event relates to if any
requirement requirement requirement the event relates to if any
comments array of comments (comment) list of comments for the related asset
attachments array of attachments (attachment) list of files attached to the related asset

 

Defect

An issue in Testlab.

Property Type Description
id id (long) the unique primary key of the defect
defectId defectId (string) human-readable defect identifier, such as ATM-7
title title (string) title of the defect
description description (string) description of the defect, HTML
created created (dateTime) the timestamp of when this defect was created
createdBy createdBy (string) name of the user who created the defect
createdById createdById (long) the primary key of the user who created the defect
updated updated (dateTime) the timestamp of when this defect was updated for last time
updatedBy updatedBy (string) name of the user who updated the defect for last time
updatedById updatedById (long) the primary key of the user who updated the defect for last time
priority priority (int) the priority of the defect, by default one of

  • 1: trivial
  • 2: low
  • 3: normal
  • 4: high
  • 5: critical

Note: Field keys and values can be customized for projects. If customized, this must be taken into account in implementation.

severity severity (int) the severity of the defect, by default one of

  • 1: cosmetic
  • 2: low
  • 3: normal
  • 4: high
  • 5: blocker

Note: Field keys and values can be customized for projects. If customized, this must be taken into account in implementation.

resolution resolution (int) resolution of the defect, by default one of

  • 2: fixed
  • 3: won’t fix
  • 4: duplicate
  • 5: more info needed
  • 6: cannot repeat

Note: Field keys and values can be customized for projects. If customized, this must be taken into account in implementation.

type type (int) type of the defect, by default one of

  • 1: defect
  • 2: new feature
  • 3: enhancement
  • 4: other

Note: Field keys and values can be customized for projects. If customized, this must be taken into account in implementation.

projectId projectId (long) project id of the defect
assignedTo assignedTo (string) name of the user the defect is assigned to
assignedToId assignedToId (long) the primary key of the user the defect is assigned to
milestoneTitle milestoneTitle (string) title of the milestone defect relates to
milestoneIdentifier milestoneIdentifier (string) identifier of the milestone defect relates to
milestoneId milestoneId (long) the primary key of the milestone defect relates to
testTargetTitle testTargetTitle (string) title of the test target (version) defect relates to
testTargetId testTargetId (long) the primary key of the test target (version) defect relates to
testEnvironmentTitle testEnvironmentTitle (string) title of the test environment defect relates to
testEnvironmentId testEnvironmentId (long) the primary key of the test environment defect relates to
testCaseName testCaseName (string) name of the test case the defect relates to Deprecated: Replaced with “testCases”, see below.
testCaseId testCaseId (long) the primary key of the test case the defect relates to
executionStepId executionStepId (long) the primary key of the execution step the defect relates to
testRunTitle testRunTitle (string) title of the test run the defect relates to
testRunId testRunId (long) the primary key of the test run the defect relates to
testRunItemId testRunItemId (long) the primary key of the test run item the defect relates to
resolvedInTestTargetTitle resolvedInTestTargetTitle (string) title of the test target (version) defect was resolved in
resolvedInTestTargetId resolvedInTestTargetId (long) the primary key of the test target (version) defect was resolved in
resolved resolved (dateTime) the timestamp of when this defect was resolved
resolvedBy resolvedBy (string) name of the user who resolved the defect
resolvedById resolvedById (long) the primary key of the user who resolved the defect
active active (boolean) if set to false the defect is closed
closed closed (dateTime) the timestamp of when this defect was closed (set as !active)
closedBy closedBy (string) name of the user who closed the defect
closedById closedById (long) the primary key of the user who closed the defect
status status (int) id of the current transition workflow status
statusTitle statusTitle (string) title of the current transition workflow status
statusIcon statusIcon (string) icon of the current transition workflow status
statusColor statusColor (string) color of the current transition workflow status
testCases array of attachments (testRunItemDefect) an array of test cases linked to the defect
custom1 custom1 (string) custom field value
custom150 custom3 (string) custom field value

 

Test case

A test case in Testlab.

Property Type Description
id id (long) the unique primary key of the test case
type type (int) Type of the test case

  • 1: a manual test case
  • 2: an automated test case
version version (long) the database provided value to track object version
name name (string) name of the test case
description description (string) HTML description of the test case
priority priority (int) the priority of the test case, by default one of

  • 1: low
  • 2: normal
  • 3: high
  • 4: critical

Note: Field keys and values can be customized for projects. If customized, this must be taken into account in implementation.

created created (dateTime) the timestamp of when this test case was created
createdBy createdBy (string) name of the user who created the test case
createdById createdById (long) the primary key of the user who created the test case
updated updated (dateTime) the timestamp of when this test case was updated for last time
updatedById updatedById (long) the primary key of the user who updated the test case for last time
updatedBy updatedBy (string) name of the user who updated the test case for last time
readied readied (dateTime) the timestamp of when this test case was accepted as ready
readiedBy readiedBy (string) name of the user who accepted the test case as ready
deprecated deprecated (dateTime) the timestamp of when this test case was deprecated
deprecatedBy deprecatedBy (string) name of the user who deprecated the test case
precondition precondition (string) preconditions for the execution of the test case
postcondition postcondition (string) postconditions of the execution of the test case
parentId parentId (long) test category id of the test case
executionSteps array of executionSteps (executionStep)
assignedTo assignedTo (string) name of the user the test case is assigned to
assignedToId assignedToId (long) the primary key of the user the test case is assigned to
active active (boolean) if set to false the test case is deprecated
ready ready (boolean) if set to true the test case is accepted as ready
currentVersionId currentVersionId (long) if a new version of this test case exists,
this value holds the primary key of the current latest version of the test case
milestoneTitle milestoneTitle (string) title of the target milestone test case relates to
milestoneIdentifier milestoneIdentifier (string) identifier of the target milestone test case relates to
milestoneId milestoneId (long) the primary key of the target milestone test case relates to
status status (int) id of the current transition workflow status
statusTitle statusTitle (string) title of the current transition workflow status
statusIcon statusIcon (string) icon of the current transition workflow status
statusColor statusColor (string) color of the current transition workflow status
automation automation (string) The Automation rule value for the (automated) test case
custom1 custom1 (string) custom field value
custom150 custom150 (string) custom field value

 

Execution step

An execution step in a test case.

Property Type Description
id id (long) the unique primary key of the execution step
orderVal orderVal (float) order value (ascending order) of the execution step
description description (string) description of the execution step, text
expected expected (string) the expected end result of the execution step, text
custom1 custom1 (string) custom field value
custom10 custom10 (string) custom field value

 

Requirement

A requirement in Testlab.

Property Type Description
id id (long) the unique primary key of the requirement
clazz clazz (int) requirement class, one of

  • 0: requirement
  • 1: folder
  • 2: test requirement
  • 3: user story
version version (long) the database provided value to track object version
requirementId requirementId (string) requirement identifier
generateIdAutomatically generateIdAutomatically (boolean) if set the requirement identifier is generated automatically at server side
name name (string) requirement’s name
source source (string) source or origin of the requirement
description description (string) requirement description, HTML
type type (int) requirement type, by default one of

  • 1: functional
  • 2: look and feel
  • 3: performance
  • 4: usability
  • 5: environmental
  • 6: maintainability
  • 7: security
  • 8: business
  • 9: legal

Note: Field keys and values can be customized for projects. If customized, this must be taken into account in implementation.

importance importance (int) requirement importance, by default one of

  • 1: low
  • 2: normal
  • 3: high
  • 4: critical

Note: Field keys and values can be customized for projects. If customized, this must be taken into account in implementation.

risk risk (int) requirement risk, by default one of

  • 1: low
  • 2: medium
  • 3: high
  • 4: critical

Note: Field keys and values can be customized for projects. If customized, this must be taken into account in implementation.

created created (dateTime) the timestamp of when this requirement was created
createdBy createdBy (string) name of the user who created the requirement
createdById createdById (long) the primary key of the user who created the requirement
updated updated (dateTime) the timestamp of when this requirement was last updated
updatedBy updatedBy (string) name of the user who updated the requirement last time
updatedById updatedById (long) the primary key of the user who updated the requirement last time
readied readied (dateTime) the timestamp of when the requirement was accepted as ready
readiedBy readiedBy (string) name of the user who accepted the requirement as ready
deprecated deprecated (dateTime) the timestamp of when the requirement was deprecated
deprecatedBy deprecatedBy (string) name of the user who deprecated the requirement
parentId parentId (long) the primary key of parent requirement
projectId projectId (long) the primary key of the project the requirement belongs to
projectKey projectKey (string) key of the project the requirement belongs to
projectName projectName (string) name of the project the requirement belongs to
subRequirements array of subRequirements (requirement) list of sub requirements of the requirement
assignedTo assignedTo (string) name of the user who the requirement is assigned to
assignedToId assignedToId (long) the primary key of the user who the requirement is assigned to
active active (boolean) if set to false the requirement is deprecated
ready ready (boolean) if set to true the requirement is accepted as ready
currentVersionId currentVersionId (long) if a new version of this requirement exists,
this value holds the primary key of the current latest version of the requirement
covered covered (boolean) is the requirement marked as covered
milestoneTitle milestoneTitle (string) title of the target milestone requirement relates to
milestoneIdentifier milestoneIdentifier (string) identifier of the target milestone requirement relates to
milestoneId milestoneId (long) the primary key of the target milestone requirement relates to
status status (int) id of the current transition workflow status
statusTitle statusTitle (string) title of the current transition workflow status
statusIcon statusIcon (string) icon of the current transition workflow status
statusColor statusColor (string) color of the current transition workflow status
custom1 custom1 (string) custom field value
custom150 custom150 (string) custom field value

 

Comment

A comment in Testlab.

Property Type Description
id id (long) the unique primary key of the comment
author author (string) author of the comment
authorId authorId (long) the unique primary key of the author’s user account
text text (string) text of the comment
at at (dateTime) the timestamp of when this comment was added

 

Attachment

An attachment in Testlab.

Property Type Description
id id (long) the unique primary key of the attachment
title title (string) title of the attachment, typically the name of the attached files
contentType contentType (string) content-type of the attachment
size size (long) size in bytes
added added (dateTime) the timestamp of when this attachment was added
addedBy addedBy (string) name of the user who added this attachment
addedById addedById (long) the unique primary key of the user who added this attachment
url url (string) API URL for the attachment

 

TestRunItemDefect

A test case linked to a Defect.

Property Type Description
id id (long) the unique primary key of the link
testCaseId testCaseId (long) the unique primary key of the linked test case
testCaseName testCaseName (string) name of the linked test case
executionStepId executionStepId (long) the unique primary key of the linked test case step
testRunId testRunId (long) the unique primary key of the linked test run
testRunTitle testRunTitle (string) title of the linked test run
testRunItemId testRunItemId (long) the unique primary key of the linked test run item

 

Programming examples

Simple stand-alone programming examples on how to listen and react to Testlab’s webhook events are provided below.

 

Java
import org.apache.commons.io.IOUtils;
import org.json.JSONObject;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class WebhooksServer {
    public static final int PORT = 9876;

    // binds a server socket to port 9876 and listens for events from Testlab
    public static void main(String[] args) throws Exception {
        ServerSocket listener = new ServerSocket(PORT);
        try {
            System.out.println("Listening in port " + PORT);
            while(true) {
                new WebhookReader(listener.accept()).start();
            }
        } finally { listener.close(); }
    }

    // a thread to process a single event notification
    public static class WebhookReader extends Thread {
        private Socket socket;
        public WebhookReader(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            InputStream in = null;
            try {
                in = socket.getInputStream();
                String post = IOUtils.toString(in, "UTF-8");
                // HTTP POST, skip headers
                post = post.substring(post.indexOf("{"));
                JSONObject json = new JSONObject(post);
                // as an example, react to changes in issues' states
                String event = json.getString("event");
                JSONObject issue = json.getJSONObject("defect");
                if("TOSTATUS".equals(event) && issue != null) {
                    // "Issue TLABDEMO-8 was Resolved in project TLABDEMO"
                    System.out.println(
                        "== Issue " + issue.getString("defectId") + " was "
                        + issue.getString("statusTitle")
                        + " in project " + json.getString("project")
                    );
                }
            } catch (Exception e) { e.printStackTrace(); } finally {
                if(in != null)
                    try { in.close(); } catch (Exception e) {}
                try { socket.close(); } catch (Exception e) {}
            }
        }
    }
}

Note: Example requires commons-io and org.json:json dependencies. Build and run with Gradle by running “gradle run” with the following in your build.gradle:

apply plugin: 'java'
apply plugin: 'application'
dependencies {
    compile 'org.apache.commons:commons-io:1.3.2'
    compile 'org.json:json:20140107'
}

mainClassName = "WebhooksServer"

Additional note: In real-world use, you probably want to run your endpoints in an application server such as Apache Tomcat and use proper API’s to build your JSON consuming endpoints (such as JAX-RS).

 

Node.js
var http = require('http');
const PORT = 9876;

var server = http.createServer(function handleRequest(req, res) {
    var b = '';
    req.on('data', function(chunk) {
        b += chunk.toString();
    });
    req.on('end', function() {
       var json = JSON.parse(b);
       // as an example, react to changes in issues' states
       var event = json['event'];
       var issue = json['defect'];
       if(event == 'TOSTATUS' && issue != null) {
           console.log(
               '= Issue ' + issue['defectId'] + ' was ' + issue['statusTitle']
               + ' in project ' + json['project']
           );
       }
    });
});

server.listen(PORT, function() {
    console.log("Listening in port %s", PORT);
});

PHP
$post = file_get_contents('php://input');
$json = json_decode($post);
// as an example, react to changes in issues' states
$event = $json->{'event'};
$issue = $json->{'defect'};
if($event = 'TOSTATUS' && $issue != null) {
    error_log(
        '== Issue ' . $issue->{'defectId'} . ' was ' .
        $issue->{'statusTitle'} . ' in project ' . $json->{'project'}
    );
}

 

Frequently asked questions

 

In short – what exactly does this do?

Webhooks are HTTP-protocol driven callbacks you can use to react to events in your Testlab instance. To do that, you can program an interface that will be called with information describing the event that happened.

 

From where exactly do I set this up with?

In Testlab, via notice schemes. You can read more about notice schemes from the Help manual of Testlab.

The interface Testlab will call and pass the notification to should be implemented by you.

  

Can I use any programming language I want?

Yes. As long as you can implement a simple HTTP listener to catch the POST’s Testlab sends and parse the JSON encoded payload delivered, you are good to go.

 

When actually are the webhook calls made?

When an event happens in Testlab which should trigger a rule in your notice scheme, the webhook call is queued for delivery. This queue is purged once in 10 seconds, so, without factoring in the network delays and such the webhook call should be made in 10 seconds at the latest.

 

I’m not receiving any webhook calls?

If you are not receiving any webhook calls, make sure that

  • you have set up the notice scheme rules correctly and the notice scheme is active,
  • the project you are testing with has this notice scheme assigned for it,
  • the Destination URL in your notice scheme rules is correct,
  • the Destination URL address points to a server which is publicly visible via internet and
  • the server you are passing the webhook callbacks to has firewall rules set up so that the HTTP post gets through.

If you still are having trouble getting the webhook calls to work, feel free to contact support and we’ll help you through it.

 



 
 
Best-of-class cross-browser hosted SaaS quality and test management, testing and issue management tools to improve your quality. Site information.