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:
- 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.
- 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.
- 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. - Save the notice scheme rules by clicking the “Save” button.
- 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
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 testCaseNametestCaseName (string)name of the test case the defect relates toDeprecated: Replaced with “testCases”, see below.testCaseIdtestCaseId (long)the primary key of the test case the defect relates toexecutionStepIdexecutionStepId (long)the primary key of the execution step the defect relates totestRunTitletestRunTitle (string)title of the test run the defect relates totestRunIdtestRunId (long)the primary key of the test run the defect relates totestRunItemIdtestRunItemId (long)the primary key of the test run item the defect relates toresolvedInTestTargetTitle 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
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 casemilestoneTitle 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
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 requirementcovered 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
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
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.