Technical description

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

    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:

      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.