Getting Started with Testworthy APIs

Introduction:

Testworthy’s API can be used for various tasks such as to integrate Testworthy with various tools, frameworks and third-party applications. For example, many customers use the API to integrate their automated tests and submit test results to Testworthy. It can also be used to:

  1. Mark results for testcases
  2. Migrate test cases from legacy systems
  3. Create test runs and cases programmatically
  4. Mark Test run Complete
  5. Delete Test runs and cases

Testworthy API is HTTP-based, so it can be used virtually from any framework, programming language, or tool. Sending data to Testworthy through the API is done with a simple POST request. Data is requested through a GET request. All requests and responses use JSON format and UTF-8 encoding.

Want to know more about Testworthy’s entities such as cases, runs & results, suites etc? Please refer to Testworhty’s User Guide under Documentation and Getting started document.

Conventions Used in Testworthy APIs:

Variables with curly braces:

Replace any values with curly braces { } in API requests with actual parameters.

For example, in the following GET API request, https://{hostname}/api/tests/get_cases/{suite_id}, replace {suite_id} with the actual value for your suite id.

So, if your suite id is 1234, the request would be https://{hostname}/api/tests/get_cases/1234

How to find Headers for API calls?

Every Testworthy API requires Header parameters in order to access the correct tenant and project details for APIs.

In the below section, you will learn where to find specific Headers in Testworthy UI and how to use them.

  1. Login to Testworthy. (Admin)
  2. Go to Integration
  3. Click on Testworthy Configuration Tab
API Headers

How to find Variables for API calls?

Many Testworthy API endpoints require you to add an ID value in the request URL or body to specify certain suite, section, cases, test runs, and more.

You can follow below steps to find specific IDs in Testworthy UI and use them as a parameter in an API request.

Suite ID:

  1. Login to Testworthy.
  2. Go to Projects.
  3. Click on Project name.
  4. Click on Test suites and cases tab.
  5. Click on Test suite name.
  6. Check the URL. The numeric characters you see before section ID is the suite ID.
API Headers

Section ID:

  1. Login to Testworthy.
  2. Go to Projects.
  3. Click on Project name.
  4. Click on Test suites and cases tab.
  5. Click on Test suite name.
  6. Click on Filters.
  7. Click on Sections.
  8. Select the section you need ID for.
  9. Click on Apply filter.
  10. Check the numeric value along with section name beside Filter.
API Headers

Case ID:

  1. Login to Testworthy.
  2. Go to Projects.
  3. Click on Project name.
  4. Click on Test suites and cases tab.
  5. Click on Test suite name.
  6. Check the Numeric value Under Case ID.
API Headers

Run ID:

  1. Login to Testworthy.
  2. Go to Projects.
  3. Click on Project name.
  4. Click on Test Run and Results tab.
  5. Click on Test Run name.
  6. Check the URL. The numeric characters you see at the end of the URL is the Run ID.
API Headers

Mapping IDs for API calls

Many Testworthy API endpoints require you to add Priority, Status or Type ID in the parameter to filter out cases in a suite or in a run.

You can use the tables given below to map specific IDs in Testworthy UI and use them as a parameter in an API request.

Type IDs:

Id Name
1 Acceptance
2 Automated
3 Compatibility
4 Destructive
5 Functional
6 Non-Functional
7 Other
8 Performance
9 Regression
10 Security
11 Smoke & Sanity
12 Accessibility
13 API
14 Negative
15 Usability
16 User Interface

Priority Ids:

Id Name ShortName
1 P3 - Good to Test Low
2 P2 - Should Test Medium
3 P1 - Must Test High

Status Ids:

Id Name
2 Blocked
5 Failed
6 Partial
1 Passed
4 Retest
3 Untested

Accessing the Testworthy APIs

Testworthy's API is HTTP-based and you can interact with it using simple HTTP requests. All read requests must use the HTTP GET method and write requests must use the HTTP POST method. Data is transferred in JSON format and UTF-8 encoding.

Authentication

Testworthy needs the authentication Headers to be provided via standard HTTP basic authentication for the API. Please ask your Testworthy administrator if you do not know which values to use as headers or follow How to find Headers for API call.


 Curl --header 'X-TMA-KEY: XbbJDvt5frZnbRekGqf2'\ 
 --header 'X-USER-EMAIL: example@testworthy.com'\
 --header 'X-PROJECT-KEY: LdGuDGdWgGZJxN7v3V93'\
 --header 'Content-Type: application/json'\

Example GET Request:

The below example shows a simple GET request to read a test run. In the given example, cURL command line tool is used to send the request, but any HTTP tool or library will work. Please note that all user names, passwords and URLs used in the example are samples only.


 curl --location --request GET 'https://example.us/ api/tests/get_runs/1234' \
 --header 'X-TMA-KEY: XbbJDvt5frZnbRekGqf2' \
 --header 'X-USER-EMAIL: example@testworthy.com' \
 --header 'X-PROJECT-KEY: LdGuDGdWgGZJxN7v3V93' \
 --header 'Content-Type: application/json'

Details of the above request:

Part Description
https://example.us Server Address
api/tests The path of Testworthy API
/get_runs The API Method that is called
/1234 An argument for the API method
X-TMA-KEY Required Header
X-USER-EMAIL Required Header
X-PROJECT-KEY Required Header
Content-Type: application/json Required Header

Actual HTTP request and response is as follow:
GET https://example.us/api/tests/get_runs/1234
Host: example.us

  

 Content-Type: application/json
 Status: 200 OK
 Content-Type: application/json; charset=utf-8

 {
 "runs": [
 {
 "suiteId": 1234,
 "milestoneId": 4334,
 "userId": 1616,
 ...
 }
 ]
 }


Example POST Request:


 curl --location --request POST 'http://example.us/api/tests/add_case/1234/12345'\
 --header 'X-TMA-KEY: XbbJDvt5frZnbRekGqf2'\
 --header 'X-USER-EMAIL: example@testworthy.com'\
 --header 'X-PROJECT-KEY: LdGuDGdWgGZJxN7v3V93'\
 --header 'Content-Type: application/json'\
 --data-raw '{ "title": "Testcase from API", }'

Details of the above request:

Part Description
https://example.us Server Address
api/tests The path of Testworthy API
/add_case The API Method that is called
/1234/12345 An argument for the API method
X-TMA-KEY Required Header
X-USER-EMAIL Required Header
X-PROJECT-KEY Required Header
Content-Type: application/json Required Header

POST http://example.us/api/tests/add_case/1234/12345
Host: example.us
Content-Type: application/json


 Content-Type: application/json
 {
 "title": "Testcase from API",
 "estimate": "5 Days",
 "reviewed_by_qa_manager": true
 }
 Status: 200 OK
 Content-Type: application/json; charset=utf-8
 {
 "id": 131741,
 "title": "Testcase2 from API",
 ..
 }

Error Handling

Following are the Response code, user can encounter while using Testworthy APIs. Successful responses use a 2xx status code, client-side errors use 4xx and server-side error use 5xx status code.

Response Codes

Status Code Description
200 Success
400 Requested entity does not exist or the body has bad syntax
401 Authentication failed due to wrong headers or credentials
403 Access denied because of limited permissions
500 Server Error

Cases

Following API Methods can be used to get data about test cases or to create, update and delete test cases.

Get Testcases using Suite ID:

It will return list of test cases in that particular suite for which the method is called. User of the API needs suite id created from front end and it will fetch all the testcases in that particular suite

Http method: GET


url: https://{hostname}/api/tests/get_cases/{suite_id}

*Please note, you would need to replace {hostname} with the actual URL for your TestWorthy instance. ** “{suite_id}” should be replaced by the Test Suite ID which must belong to the project specified by X-PROJECT-KEY header.

Headers:

  • *X-TMA-KEY (Api key)
  • *X-USER-EMAIL (user email)
  • *X-PROJECT-KEY (project key)

Parameters:

Name Type Is Required Description Example
suite_id Integer True The ID of the test suite which must belong to the project. https://{hostname}/api/testcase/get_cases/1370
automated Boolean False test cases list will be filtered by Automated property. Possible values for this parameter (true/false) https://{hostname}/api/testcase/get_cases/1370?automated=true&disabled=false
to_automate Boolean False test cases list will be filtered by ToAutomate property. Possible values for this parameter https://{hostname}/api/testcase/get_cases/1370?to_automate=true
disabled Boolean False test cases list will be filtered by Disabled property. Possible values for this parameter (true/false) https://{hostname}/api/testcase/get_cases/1370?automated=true&disabled=false
reviewed_by_qamanager Boolean False test cases list will be filtered by ReviewedByQAManager property. Possible values for this parameter (true/false)
reviewed_by_qalead Boolean False test cases list will be filtered by ReviewedByQALead property. Possible values for this parameter (true/false)
reviewed_by_pm Boolean False test cases list will be filtered by ReviewedByPM property. Possible values for this parameter (true/false)
regression Boolean False test cases list will be filtered by Regression property. Possible values for this parameter (true/false)
smoke Boolean False test cases list will be filtered by Smoke property. Possible values for this parameter (true/false)
created_by String False a comma-separated list of creators (user IDs) to filter by. Each user ID must be an Integer https://{hostname}/api/testcase/get_cases/1370?created_by=1798,1258,1688
created_after String False only return Test Cases created after this date. it must have the following format: dd-MM-yyyy https://{hostname}/api/testcase/get_cases/1370?created_after=19-05-2021
created_before String False only return Test Cases created before this date. it must have the following format: dd-MM-yyyy https://{hostname}/api/testcase/get_cases/1370?created_before=31-12-2022
priority_ids String False a comma-separated list of priority IDs to filter by
jira_reference String False a comma-separated list of Jira Reference ID (e.g. TW-100, etc.)
github_reference String False a comma-separated list of GitHub Reference ID (e.g. 1,2, etc.)
azure_reference String False a comma-separated list of AzureDevOps Reference ID (e.g. 1,2, etc.)
section_id Integer False the ID of the section for each Test Case https://{hostname}/api/testcase/get_cases/1370?section_id=9978
title String False only return Test Cases which title property contains the value for this parameter https://{hostname}/api/testcase/get_cases/1370?title=credentials
type_ids String False a comma-separated list of case type IDs to filter by
page_limit Integer False the number of Test Cases the response should return (The response size is 250 by default) https://{hostname}/api/testcase/get_cases/1370?page_limit=50
page_number Integer False the page number where to start taking the Test Cases. (This parameter is 1 by default). example, the total count for the existing Test Cases is 100, you send the page_limit parameter as 50, so the response will be the first 50 records, but if you send the page_number parameter as 2, so the response will be the next 50 records. https://{hostname}/api/testcase/get_cases/1370?page_number=2&page_limit=50

Responses:

200:
*Everything is Ok then the response is a list with test cases.

Response Content: (example)



{
"page_number": 1,
"page_limit": 5,
"page_size": 5,
"total_count": 9,
"_links": {
"next": "/api/testcase/get_cases/1370?&page_number=2&page_limit=5",
"previous": null
},
"cases": [
{
"sectionId": 9978,
"title": "TC 1 Login with valid credentials",
"displayOrder": 0,
"priorityId": 3,
"estimate": 20,
"milestoneId": null,
"customPreconds": null,
"customSteps": null,
"customExpected": null,
"customStepsSeparated": null,
"customMission": null,
"customGoals": null,
"testData": null,
"typeId": 11,
"isCopy": false,
"copyofId": null,
"userId": 1688,
"estimateForecast": null,
"jira_refs": null,
"github_refs": null,
"azure_refs": null,
"suiteId": 1370,
"templateId": 1,
"tenantId": null,
"smoke": false,
"regression": false,
"reviewedbyQALead": false,
"toAutomate": true,
"user": {
"firstName": "DEV",
"lastName": "Environment"
},
"section": null,
"suite": {
"name": "copiable",
"id": 1370
},
"lastModifiedOn": "2022-05-20T20:33:00.9841955"
},
...
]
}

400:

  • *If page_number parameter specified by the user is less than 1, this parameter must be greater than Zero.
  • *If page_limit parameter is out of range, it must be between 1 and 250.
  • *If Test suite was not found by the specified suite_id parameter, Invalid or unknown test suite.
  • *If the test suite specified by suite_id parameter does not belong to project specified by X-PROJECT-KEY header.
  • *if createdAfter parameter is specified and it does not match the following format: “dd-MM-yyyy”.
  • *if createdBefore parameter is specified and it does not match the following format: “dd-MM-yyyy”.

401:

  • *If “X-TMA-KEY” header was not provided or it is not valid.
  • *If no user was found by “X-USER-EMAIL” header.
  • *If “X-PROJECT-KEY” header is not valid.

Get Testcases using Run ID:

It will return list of test cases in that particular run for which the method is called. User of the API needs run id created from front end and it will fetch all the testcases in that particular run.

Http method: GET


url: https://{hostname}/api/tests/get_run_cases/{run_id} 

Headers:

  • *X-TMA-KEY (Api key)
  • *X-USER-EMAIL (user email)
  • *X-PROJECT-KEY (project key)

Parameters:

Name Type Is Required Description Example
run_id Integer True The ID of the test run which must belong to the project. https://{hostname}/api/testcase/get_run_cases/1370
automated Boolean False Test cases list will be filtered by Automated property. Possible values for this parameter (true/false) https://{hostname}/api/testcase/get_run_cases/1370?automated=true&disabled=false
to_automate Boolean False Test cases list will be filtered by ToAutomate property. Possible values for this parameter https://{hostname}/api/testcase/get_run_cases/1370?to_automate=true
disabled Boolean False Test cases list will be filtered by Disabled property. Possible values for this parameter (true/false) https://{hostname}/api/testcase/get_run_cases/1370?automated=true&disabled=false
reviewed_by_QAmanager Boolean False Test cases list will be filtered by ReviewedByQAManager property. Possible values for this parameter (true/false)
reviewed_by_QAlead Boolean False Test cases list will be filtered by ReviewedByQALead property. Possible values for this parameter (true/false)
reviewed_by_PM Boolean False Test cases list will be filtered by ReviewedByPM property. Possible values for this parameter (true/false)
regression Boolean False Test cases list will be filtered by Regression property. Possible values for this parameter (true/false)
smoke Boolean False Test cases list will be filtered by Smoke property. Possible values for this parameter (true/false)
assigned_to_id Integer False Only those test cases will be returned that have been assigned to this particular User ID. https://{hostname}/api/testcase/get_run_cases/1370?assigned_to_id=1798,1258,1688
tested_by_id Integer False Only those test cases will be returned that have been tested by this particular user ID. https://{hostname}/api/testcase/get_run_cases/1370?tested_by_id=19-052021
Status_ids String False Comma Separated list of Status IDs (this can be mapped by help of this table) https://{hostname}/api/testcase/get_cases/1370?Status_ids=1
priority_ids String False A comma-separated list of priority IDs to filter by. (this can be mapped by help of this table)
jira_reference String False A comma-separated list of Reference ID (e.g., TW-100, etc.)
github_reference String False a comma-separated list of GitHub Reference ID (e.g. 1,2, etc.)
azure_reference String False a comma-separated list of AzureDevOps Reference ID (e.g. 1,2, etc.)
title String False Only return Test Cases which title property contains the value for this parameter https://localhost:44330/api/testcase/get_run_cases/1370?title=credentials
type_ids String False A comma-separated list of case type IDs to filter by. (this can be mapped by help of this table)
page_limit Integer False The number of Test Cases the response should return (The response size is 250 by default) https://{hostname}/api/testcase/get_run_cases/1370?page_limit=50
page_number Integer False The page number where to start taking the Test Cases. (This parameter is 1 by default). Example, the total count for the existing Test Cases is 100, you send the pageLimit parameter as 50, so the response will be the first 50 records, but if you send the pageNumber parameter as 2, so the response will be the next 50 records. https://{hostname}/api/testcase/get_run_cases/1370?page_number=2&page_limit=50
defects String False Only those test cases will be returned whose defects field matches the one entered
defect_type String False Only those test cases will be returned whose defect issue type matches the one entered i.e Jira/GitHub/AzureDevOps

Responses:

200:
*Everything is Ok then the response is a list with test cases.

Response Content: (example)


    
        "tests": [
        {
        "id": 183005,
        "runId": 6339,
        "caseId": 136940,
        "statusId": 1,
        "previousStatusId": 0,
        "assignedtoId": 1688,
        "lastStatusChangeId": 0,
        "isCompleted": false,
        "inProgress": 0,
        "inProgressBy": 0,
        "testedBy": 1688,
        "defects": null,
        "defectIssueType": null,
        "case": {
        "id": 136940,
        "title": "case 1",
        "display_order": 29,
        "estimate": 2,
        "estimate_timespan": null,
        "milestone_id": null,
        "custom_preconds": "test",
        "custom_steps": "1\r\n\r\n2\r\n\r\n3",
        "custom_expected": "1\r\n\r\n2\r\n\r\n3",
        "custom_steps_separated": null,
        "custom_mission": null,
        "custom_goals": null,
        "test_data": "test",
        "is_copy": false,
        "copy_of_id": null,
        "estimate_forecast": 0,
        "jira_refs": null,
        "github_refs": null,
        "azure_refs": null,
        "template_id": 1,
        "tenant_id": 1428,
        "smoke": true,
        "regression": true,
        "reviewed_by_qa_lead": true,
        "reviewed_by_qa_manager": true,
        "reviewed_by_pm": true,
        "to_automate": true,
        "automation_type": null,
        "priority": null,
        "user": {
        "id": 1688,
        "name": "DEV Environment"
        },
        .
        .
        .
    

400:

  • *If pageNumber parameter specified by the user is less than 1, this parameter must be greater than Zero.
  • *If PageLimit parameter is out of range, it must be between 1 and 250.
  • *If Test run was not found by the specified run_id parameter, Invalid or unknown test run.
  • *If the test run specified by run_id parameter does not belong to project specified by X-PROJECT-KEY header.

401:

  • *If “X-TMA-KEY” header was not provided or it is not valid.
  • *If no user was found by “X-USER-EMAIL” header.
  • *If “X-PROJECT-KEY” header is not valid.

Create Testcase using Suite ID and Section ID:

It will create a new testcase under the section and suite for which the method is called. User of the API need needs section and suite id and they can get it from the URL of the application. The testcase will be created in the provided suite and section.

Http method: POST


url: https://{hostname}/api/tests/add_case/{suite_id}/{section_id}

** “{suite_id}” should be replaced by the Test Suite ID which must belong to the project specified by X-PROJECT-KEY header.
** “{section_id}” should be replaced by the Test Suite ID which must belong to the Test Suite specified by suite_id parameter and the project specified by X-PROJECT-KEY header.
*Please note, you would need to replace {hostname} with the actual URL for your TestWorthy instance.

Headers:

  • *X-TMA-KEY (Api key)
  • *X-USER-EMAIL (user email)
  • *X-PROJECT-KEY (project key)
  • *Content-Type = application/json

Body:

(example)


 {
 "title":"creation from API",
 "estimate":"5days",
 "reviewed_by_qa_manager":true
 }

Parameters:

Name Type Is Required Description
suite_id Integer True The Test Suite ID which the Test Case is going to be added to.
section_id Integer True The Section ID which the Test Case is going to be added to. This section must belong to the Test Suite specified by “suite_id” parameter.
title String True The title of the new Test Case.
milestone_id Integer False The ID of the milestone to link to the test case
template_id Integer False The ID of the template (field layout)
type_id Integer False The ID of the case type
priority_id Integer False The ID of the case priority
estimate Timespan False The estimate, e.g. “45s” or “2days”. more examples: 1s - 1second - 2seconds 1m - 1min - 2mins - 1minute - 2minutes 1h - 1hour - 2hours 1d - 1day - 2days 1w - 1week - 2weeks
jira_refs String False The reference/issue ID of linked Jira issue
github_refs String False The reference/issue ID of linked GitHub issue
azure_refs String False The reference/work-item ID of linked AzureDevOps work-item.
smoke Boolean False If Test Case is smoke
regression Boolean False If Test Case is for regression
reviewed_by_qa_lead Boolean False If Test Case is reviewed by QA lead
reviewed_by_qa_manager Boolean False If Test Case is reviewed by QA manager
reviewed_by_pm Boolean False If Test Case is reviewed by PM
to_automate Boolean False If Test Case is to automate
custom_preconds String False Custom field
custom_steps String False Custom field
custom_expected String False Custom field
custom_steps_separated String False Custom field
custom_mission String False Custom field
custom_goals String False Custom field
test_data String False Custom field
custom_desc String False Custom field
custom_bdd_gherkin String False Custom field
custom_cucumber_tags String False Custom field
custom_module Boolean False If this custom field is true or false
custom_disabled Boolean False If this custom field is true or false
custom_automated Boolean False If this custom field is true or false
custom_tobemoved Boolean False If this custom field is true or false

Responses:

200:
*Everything is Ok then the response is the new Test Case added.

(Example):

    
        {
        "id": 101486,
        "title": "creation from API",
        "display_order": 0,
        "estimate": 7200,
        "milestone_id": null,
        "custom_preconds": null,
        "custom_steps": null,
        "custom_expected": null,
        "custom_steps_separated": null,
        "custom_mission": null,
        "custom_goals": null,
        "test_data": null,
        "is_copy": false,
        "copy_of_id": null,
        "estimate_forecast": null,
        "jira_refs": null,
        "github_refs": null,
        "azure_refs": null,
        "template_id": 1,
        "tenant_id": 1428,
        "smoke": false,
        "regression": false,
        "reviewed_by_qa_lead": false,
        "reviewed_by_qa_manager": true,
        "reviewed_by_pm": false,
        "to_automate": false,
        "automation_type": null,
        "priority": {
        "short_name": "High",
        "id": 3,
        "name": "P1 - Must Test"
        },
        "user": {
        "user_name": "stdev@yopmail.com",
        "email": "stdev@yopmail.com",
        "role_id": 1,
        "designation_id": null,
        "tenant_id": 1428,
        "role_name": null,
        "id": 1688,
        "name": "DEV Environment"
        },
        "type": {
        "id": 5,
        "name": "Functional"
        },
        "section": {
        "suite_id": 1370,
        "is_copy": false,
        "copy_of_id": null,
        "parent_id": null,
        "description": null,
        "tenant_id": 1428,
        "created_by": 1688,
        "created_on": "2022-01-18T20:44:29.9296591",
        "last_modified_by": 1688,
        "last_modified_on": "2022-01-18T20:44:29.9296627",
        "id": 9978,
        "name": "added moved"
        },
        "suite": {
        "project_id": 1326,
        "description": null,
        "is_copy": false,
        "copy_of_id": null,
        "is_master": true,
        "is_baseline": true,
        "parent_id": null,
        "is_completed": false,
        "completed_on": null,
        "tenant_id": 1428,
        "id": 1370,
        "name": "copiable"
        },
        "custom_module": false,
        "custom_disabled": false,
        "custom_automated": false,
        "custom_tobemoved": false,
        "custom_desc": null,
        "custom_bdd_gherkin": null,
        "custom_cucumber_tags": null,
        "rail_case_id": null,
        "created_by": 1688,
        "created_on": "2022-07-27T10:35:13.8045951-05:00",
        "last_modified_by": 1688,
        "last_modified_on": "2022-07-27T10:35:13.8045951-05:00"
        }
    

400:

  • Suite not found with "suite_id" or the suite does not belong to the project found by "X-PROJECT-KEY" sent through header.
  • Json model sent through Body is not ok or is empty.
  • "title" property is Null, Empty or Whitespace.
  • Section not found with "section_id" or the Section does not belong to the Test Suite specified by "suite_id" and it does not belong to the project found by "X-PROJECT-KEY" sent through header.
  • If the "milestone_id" property has a value, the API could respond that the Milestone was not found with "milestone_id" or the milestone does not belong to the project found by "X-PROJECT-KEY" sent through header.
  • If the "priority_id" has a value, it is an invalid or unknown Priority with the "priority_id".
  • If the "template_id" has a value, it is an invalid or unknown Priority with the "template_id".
  • If the "type_id" has a value, it is an invalid or unknown Priority with the "type_id".
  • The Estimate must be a timespan, invalid timespan (Note: see the parameter table to know the possible options).

401:

  • If "X-TMA-KEY" header was not provided or it is not valid.
  • If no user was found by "X-USER-EMAIL" header.
  • If "X-PROJECT-KEY" header is not valid or any valid project was found with its value.

Update Testcase:

It will update the existing testcase for which the method is called. User need the Id of that particular testcase that they want to update and can get it from the application.

Http method: POST


url: https://{hostname}/api/tests/update_case/{case_id}

** “{case_id}” should be replaced by the Test Case ID which must belong to the project specified by X-PROJECT-KEY header.
*Please note, you would need to replace {hostname} with the actual URL for your TestWorthy instance.

Headers:

  • X-TMA-KEY (Api key)
  • X-USER-EMAIL (user email)
  • X-PROJECT-KEY (project key)
  • Content-Type = application/json

Body:

(example)

  

 {
 "estimate": "5days",
 "reviewed_by_qa_manager": true
 }

Parameters:

Name Type Is Required Description
section_id Integer False The Section ID which the Test Case is going to be added to. This section must belong to the project specified by X-PROJECT-KEY header
title String False The title of the new Test Case.
milestone_id Integer False The ID of the milestone to link to the test case
template_id Integer False The ID of the template (field layout)
type_id Integer False The ID of the case type
priority_id Integer False The ID of the case priority
estimate Timespan False The estimate, e.g. "45s" or "2days".
jira_refs String False The reference/issue ID of linked Jira issue
github_refs String False The reference/issue ID of linked GitHub issue
azure_refs String False The reference/work-item ID of linked AzureDevOps work-item.
smoke Boolean False If Test Case is smoke
regression Boolean False If Test Case is for regression
reviewed_by_qa_lead Boolean False If Test Case is reviewed by QA lead
reviewed_by_qa_manager Boolean False If Test Case is reviewed by QA manager
reviewed_by_pm Boolean False If Test Case is reviewed by PM
to_automate Boolean False If Test Case is to automate
custom_preconds String False Custom field
custom_steps String False Custom field
custom_expected String False Custom field
custom_steps_separated String False Custom field
custom_mission String False Custom field
custom_goals String False Custom field
test_data String False Custom field
custom_desc String False Custom field
custom_bdd_gherkin String False Custom field
custom_cucumber_tags String False Custom field
custom_module Boolean False If this custom field is true or false
custom_disabled Boolean False If this custom field is true or false
custom_automated Boolean False If this custom field is true or false
custom_tobemoved Boolean False If this custom field is true or false
section_id Integer False The Section ID which the Test Case is going to be added to. This section must belong to the project specified by X-PROJECT-KEY header

Responses:

200:
*Everything is Ok then the response is the Test Case updated.

(Example):

    
        {
        "id": 101486,
        "title": "update made from API",
        "display_order": 0,
        "estimate": 7200,
        "milestone_id": null,
        "custom_preconds": null,
        "custom_steps": null,
        "custom_expected": null,
        "custom_steps_separated": null,
        "custom_mission": null,
        "custom_goals": null,
        "test_data": null,
        "is_copy": false,
        "copy_of_id": null,
        "estimate_forecast": null,
        "jira_refs": null,
        "github_refs": null,
        "azure_refs": null,
        "template_id": 1,
        "tenant_id": 1428,
        "smoke": false,
        "regression": false,
        "reviewed_by_qa_lead": false,
        "reviewed_by_qa_manager": true,
        "reviewed_by_pm": false,
        "to_automate": false,
        "automation_type": null,
        "priority": {
        "short_name": "High",
        "id": 3,
        "name": "P1 - Must Test"
        },
        "user": {
        "user_name": "stdev@yopmail.com",
        "email": "stdev@yopmail.com",
        "role_id": 1,
        "designation_id": null,
        "tenant_id": 1428,
        "role_name": null,
        "id": 1688,
        "name": "DEV Environment"
        },
        "type": {
        "id": 5,
        "name": "Functional"
        },
        "section": {
        "suite_id": 1370,
        "is_copy": false,
        "copy_of_id": null,
        "parent_id": null,
        "description": null,
        "tenant_id": 1428,
        "created_by": 1688,
        "created_on": "2022-01-18T20:44:29.9296591",
        "last_modified_by": 1688,
        "last_modified_on": "2022-01-18T20:44:29.9296627",
        "id": 9978,
        "name": "added moved"
        },
        "suite": {
        "project_id": 1326,
        "description": null,
        "is_copy": false,
        "copy_of_id": null,
        "is_master": true,
        "is_baseline": true,
        "parent_id": null,
        "is_completed": false,
        "completed_on": null,
        "tenant_id": 1428,
        "id": 1370,
        "name": "copiable"
        },
        "custom_module": false,
        "custom_disabled": false,
        "custom_automated": false,
        "custom_tobemoved": false,
        "custom_desc": null,
        "custom_bdd_gherkin": null,
        "custom_cucumber_tags": null,
        "rail_case_id": null,
        "created_by": 1688,
        "created_on": "2022-07-27T10:35:13.8045951-05:00",
        "last_modified_by": 1688,
        "last_modified_on": "2022-07-27T10:35:13.8045951-05:00"
        }
    

400:

  • If no Test Case was found with the specified {case_id}.
  • Section not found with "section_id" or it does not belong to the project found by "X-PROJECT-KEY" sent through header.
  • If the "milestone_id" property has value, so API could respond that the Milestone was not found with "milestone_id" or the milestone does not belong to the project found by "X-PROJECT-KEY" sent through header.
  • If the "priority_id" has a value, invalid or unknown Priority with the "priority_id".
  • If the "template_id" has a value, invalid or unknown Priority with the "template_id".
  • If the "type_id" has a value, invalid or unknown Priority with the "type_id".
  • The Estimate must be a timespan, invalid timespan (Note: see parameter table to know the possible options).

401:

    • If "X-TMA-KEY" header was not provided or it is not valid.
    • If no user was found by "X-USER-EMAIL" header.
    • If "X-PROJECT-KEY" header is not valid or no valid project was found with its value.

Delete Testcase:

It will delete the test case for which the method Is called. User need the Id of the testcase that they want to delete and can get it from the application.

Http method: DELETE


url: https://{hostname}/api/tests/delete_case/{case_id}

** “{case_id}” should be replaced by the Test Case ID which must belong to the project specified by X-PROJECT-KEY header.
*Please note, you would need to replace {hostname} with the actual URL for your TestWorthy instance.

Headers:

  • X-TMA-KEY (Api key)
  • X-USER-EMAIL (user email)
  • X-PROJECT-KEY (project key)

Responses:

200:
*Everything is Ok then the response is the Test Case deleted (same model returned in Create Test Caseby Suite ID and Section ID).

400:

*No Test Case was found with the specified {case_id}.

401:

  • If "X-TMA-KEY" header was not provided or it is not valid.
  • If no user was found by "X-USER-EMAIL" header.
  • If "X-PROJECT-KEY" header is not valid or no valid project was found with its value.

Runs:

Following API Methods can be used to get data about the test runs or to create, update, delete or mark complete a test run.

Create Test Run:

It will create a test run with all the test cases in the specified suite in the body or with the test cases specified in the test case array in the body. User need to send suite id in body of the request. All testcases in that suite will be added to the test run

Http method: POST


url: https://{hostname}/api/tests/add_run

*Please note, you would need to replace {hostname} with the actual URL for your TestWorthy instance.

Headers:

  • *X-TMA-KEY (Api key)
  • *X-USER-EMAIL (user email)
  • *X-PROJECT-KEY (project key)
  • *Content-Type = application/json

Body:

(example)

 

 {
 "name": "Postman Test Run",
 "description": "Test made from Postman",
 "milestone_id": null,
 "assignedto_id": null,
 "suite_id": 1370,
 "include_all": true,
 "case_ids": []
 }


Parameters:

Property Name Description Nullable
name Name for the new test run to be added No
description Description for the new test run to be added Yes
milestone_id It is the milestone Id which the new test run is going to belong. This property is nullable, but if user send a value, it must be a valid ID for a valid Milestone, it must belong to the project specified by the X-PROJECT-KEY header Yes
assignedto_id It is the ID for the user which is going to be assigned. This property is nullable, but if the user send a value, it must be a valid ID for a valid user, he/she must belong to the project specified by the X-PROJECT-KEY header Yes
suite_id The ID for the suite which the new test run is going to be added No
include_all Boolean property, send "true" if the new test run is going to have all the active and valid cases in the project. Send "false" if the new test run is going to have the cases specified by "case_ids" property only. No
case_ids If "include_all" property is "false", this property will not be validated. This property is a list of integers which the case ids to be added in the new test run, these ids must be for a valid Test Case and each one must belong to the Test Suite specified by “SuiteId” property otherwise, the case id will not be added. No

Responses:

200:
*Everything is Ok then the response is the new Test Run added.

400:

  • Suite not found with "suite_id" or the suite does not belong to the project found by "X-PROJECT-KEY" sent through header.
  • Json model sent through Body is not ok or is empty.
  • "name" property is Null, Empty, or Whitespace.
  • If the "assignedto_id" has a valid number, so the value must be for a valid user and he/she must belong to the project found by "X-PROJECT-KEY" sent through header.
  • If the "milestone_id" property has a value, so the API could respond that the Milestone was not found with "milestone_id" or the milestone does not belong to the project found by "X-PROJECT-KEY" sent through header.

401:

  • If "X-TMA-KEY" header was not provided or it is not valid.
  • If no user was found by "X-USER-EMAIL" header.
  • If "X-PROJECT-KEY" header is not valid or no valid project was found with its value.

Get Run:

It will return a list of test runs for the specified suite for which the method is called. To get a test run user need to pass test run id that they can get from the URL in the application.

Http method: GET


url: https://{hostname}/api/tests/get_runs/{suite_id}

** “{suite_id}” should be replaced by the Test Suite ID which must belong to the project specified by X-PROJECT-KEY header.
**Please note, you would need to replace {hostname} with the actual URL for your TestWorthy instance and you need to replace “714” with a valid suite ID.

Headers:

  • *X-TMA-KEY (Api key)
  • *X-USER-EMAIL (user email)
  • *X-PROJECT-KEY (project key)

Parameters:

Name Type Is Required Description Example
suite_id true Integer The test suite ID to filter by https://{hostname}/api/tests/get_runs/714
created_after false String Only return Test Runs created after this date. It must have the following format: dd-MM-yyyy https://{hostname}/api/tests/get_runs/714?created_after=19-01-2022
created_before false String Only return Test Cases created before this date. It must have the following format: dd-MM-yyyy https://{hostname}/api/tests/get_runs/714?created_before=31-12-2022
is_completed false Boolean Send true to get only completed test runs, send false to get only uncompleted test runs. If you do not send any value, the response is going to get all test runs (completed and uncompleted) https://{hostname}/api/tests/get_runs/714?is_completed=true
page_limit false Integer The number of Test Runs the response should return. The response size is 250 by default. https://{hostname}/api/tests/get_runs/714?page_limit=50
page_number false Integer The page number where to start taking the Test Runs. This parameter is 1 by default. For example, if the total count for the existing Test Run is 100 and you send the page_limit parameter as 50, the response will be the first 50 records. If you send the page_number parameter as 2, the response will be the next 50 records. https://{hostname}/api/tests/get_runs/714?page_number=2&page_limit=50

Responses:

200:
*Everything is Ok then the response is a list with test runs.


 {
 "page_number": 1,
 "page_limit": 5,
 "page_size": 5,
 "total_count": 9,
 "_links": {
 "next": "/api/testcase/get_cases/1370?&page_number=2&page_limit=5",
 "previous": null
 },
 "runs": [
 ...
 ]
 }

400:

  • If page_number parameter specified by the user is less than 1, this parameter must be greater than Zero.
  • If page_limit parameter is out of range, it must be between 1 and 250.
  • If any Test suite was found by the specified suite_id parameter, Invalid or unknown test suite.
  • If the test suite specified by suite_id parameter does not belong to project specified by X-PROJECT-KEY header.
  • If createdAfter parameter is specified and it does not match the following format: "dd-MM-yyyy".
  • If createdBefore parameter is specified and it does not match the following format: "dd-MM-yyyy".

401:

  • If "X-TMA-KEY" header was not provided or it is not valid.
  • If no user was found by "X-USER-EMAIL" header.
  • If "X-PROJECT-KEY" header is not valid.

Update Test run:

It will update the already existing test run. To update test run, user need to pass test run id that they can get from the URL in the application.

Http method: POST


url: https://{hostname}/api/tests/update_run/{run_id}

*Please note, you would need to replace {hostname} with the actual URL for your Testworthy instance

Headers:

  • *X-TMA-KEY (Api key)
  • *X-USER-EMAIL (user email)
  • *X-PROJECT-KEY (project key)
  • *Content-Type = application/json

Body:

(example)


 {
 {
 "name": "Postman Test Run",
 "description": "Test made from Postman",
 "milestone_id": null,
 "include_all": true,
 "case_ids": []
 }

Parameters:

Property Name Description Nullable
name Name for the new test run to be added No
description Description for the new test run to be added Yes
milestone_id It is the milestone Id which the new test run is going to belong. This property is nullable, but if the user sends a value, it must be a valid ID for a valid Milestone. It must belong to the project specified by the X-PROJECT-KEY header. Yes
assignedto_id It is the ID for the user which is going to be assigned. This property is nullable, but if the user send a value, it must be a valid ID for a valid user, he/she must belong to the project specified by the X-PROJECT-KEY header Yes
include_all Boolean property, send "true" if the new test run is going to have all the active and valid cases in the project. Send "false" if the new test run is going to have the cases specified by the "case_ids" property only. No
case_ids If "include_all" property is "false", this property will not be validated. This property is a list of integers which represent the case IDs to be added in the new test run. These IDs must be for a valid Test Case and each one must belong to the Test Suite specified by “SuiteId” property otherwise, the case id will not be added. No

Responses:

200:
*Everything is Ok then the response is the Test Run updated.

400:

  • Suite not found with "suite_id" or the suite does not belong to the project found by "X-PROJECT-KEY" sent through header.
  • Json model sent through Body is not ok or is empty.
  • If the "milestone_id" property has value, the API could respond that the Milestone was not found with "milestone_id" or the milestone does not belong to the project found by "X-PROJECT-KEY" sent through header.

401:

  • If "X-TMA-KEY" header was not provided or it is not valid.
  • If no user was found by "X-USER-EMAIL" header.
  • If "X-PROJECT-KEY" header is not valid or no valid project was found with its value.

Delete Test Run:

It will delete the existing test run for which the method is called. To delete test run, user need to pass test run id that they can get from the URL in the application.

Http method: DELETE

url: https://{hostname}/api/tests/delete_run/{run_id}
*Please note, you would need to replace {hostname} with the actual URL for your Testworthy instance.

Headers:

  • X-TMA-KEY (Api key)
  • X-USER-EMAIL (user email)
  • X-PROJECT-KEY (project key)

Parameters:

Name Type Required Description
run_id integer true The ID of the test run

Responses:

200:
*Everything is Ok then the response is the Test Run deleted.

400:

  • *Test Run not found with “run_id” or the run does not belong to the project found by “X-PROJECT-KEY” sent through header.

401:

  • If "X-TMA-KEY" header was not provided or it is not valid.
  • If no user was found by "X-USER-EMAIL" header.
  • If "X-PROJECT-KEY" header is not valid or no valid project was found with its value.

Complete Test Run:

It will mark the existing test run complete. To mark a test run complete, user need to pass test run id that they can get from the URL in the application.

Http method: POST


url: https://{hostname}/api/tests/complete_run/{run_id}

*Please note, you would need to replace {hostname} with the actual URL for your Testworthy instance.

Headers:

  • *X-TMA-KEY (Api key)
  • *X-USER-EMAIL (user email)
  • *X-PROJECT-KEY (project key)

Parameters:

Name Type Required Description
run_id integer true The ID of the test run

Responses:

200:
*Everything is Ok then the response is the Test Run marked complete.

400:

  • *Test Run not found with “run_id” or the run does not belong to the project found by “X-PROJECT-KEY” sent through header.

401:

  • If "X-TMA-KEY" header was not provided or it is not valid.
  • If no user was found by "X-USER-EMAIL" header.
  • If "X-PROJECT-KEY" header is not valid or no valid project was found with its value.

Results:

Following API method can be used to get data about results of test runs.

Update Test Result:

It will mark the result of test case specified. To add result user, need to add suite id in URL

Http method: POST

url: https://{hostname}/api/tests/add_results_for_cases/{run_id}
** “{run_id}” should be replaced by the Test Run Id.
*Please note, you would need to replace {hostname} with the actual URL for your TestWorthy instance.

Headers:

  • *X-TMA-KEY (Api key)
  • *X-USER-EMAIL (user email)
  • *X-PROJECT-KEY (project key)
  • *Content-Type = application/json

Body:

(example)


 {
 "Results": [
 {
 "case_id": 82519,
 "status_id": 1,
 "Comment": "test from postman",
 "AssignedToId": null,
 "Defects": "2",
 "DefectIssueType" : "GitHub"
 },
 {
 "case_id": 82520,
 "status_id": 1,
 "Comment": "test from postman",
 "AssignedToId": 2149,
 "Defects": "2306"
 "DefectIssueType" : "Jira"
 },
 {
 "case_id": 82537,
 "status_id": 1,
 "Comment": "test from postman",
 "Defects": "3",
 "DefectIssueType": "AzureDevOps"
 }
 ]
 }

Responses:

200:
*Everything is Ok then the response is a list with the test changes

400:

  • Run not found with "run_id" or the run does not belong to the project found by "X-PROJECT-KEY" sent through header.
  • Json model is not ok or is empty.
  • Any of the "case_id" or "status_id" are invalid number (less than 1).
  • If any of the "AssignedToId" has a valid number, this value must belong to the project found by "X-PROJECT-KEY" sent through header.
  • The "case_id" must belong to the Run found by "run_id" sent through url.

401:

  • If "X-TMA-KEY" header was not provided or it is not valid.
  • If no user was found by "X-USER-EMAIL" header.
  • If "X-PROJECT-KEY" header is not valid.

Automated Test Execution with Testworthy Integration

Overview:

This section contains automation scripts for executing tests using Selenium (Java) and Playwright (Javascript) and updating the Testworthy test run. The test case titles in the scripts should match the titles in the test run.

Follow the steps below to configure and run the scripts successfully.

Selenium

Prerequisites:

  • Java Development Kit (JDK) installed on your machine
  • Selenium WebDriver for Java
  • Testworthy account with access to the desired project
  • Testworthy API key (You can obtain this from your Testworthy account settings)

Obtaining Suite ID:

  • Open the Testworthy project in your browser.
  • Navigate to the desired Suite.
  • Obtain the suite ID from the URL. It should look like .../Project/Overview/suite_id.

Running the automation scripts:

Click the green run icon beside your desired test class/test to run the tests.

Code snippets for the Selenium

Configuration:

This is the configuration file. All the required configuration needs to be added in Config.json.

  

{ 
  "Email": "abc@xyz.com", 
  "API_Key": "abc123", 
  "Project_Key": "abc123", 
  "URL": "TestworthyURL.com", 
  "Suite_ID": 1234, 
  "TestRunName": "Test_Run" 
} 


Initialization and setting the headers:

Setting up the base URL and the common headers.

  


public static void initialization() { 
    RestAssured.baseURI = Url; 
} 

public static RequestSpecification setCommonHeaders() { 
    RequestSpecification requestSpec = given() 
            .header("Content-Type", "application/json") 
            .header("X-TMA-KEY", API_Key) 
            .header("X-USER-EMAIL", Email) 
            .header("X-PROJECT-KEY", Project_Key) 
            .cookie("Your Cookies"); 
    return requestSpec; 
}


Getting Run ID from Suite ID:

Suite ID is already mentioned in Configuration, Here with the help of Suite ID, Run ID is fetched.

  

public static int getRunIDfromSuiteID() { 
    initialization(); 
    Response getResponse = setCommonHeaders(). 
            get("get_runs/" + Suite_ID); 
    getResponse.then().log().all(); 
    String jsonResponse = getResponse.asString(); 
    JsonPath = new JsonPath(jsonResponse); 
    //Getting theRunID on the basis of RunName 
    int idForDesiredRun = jsonPath.getInt("runs.find " + 
            "{ " + 
            "it.name == '" + TestRunName + "' " + 
            "}" + 
            ".id"); 
    return idForDesiredRun; 
} 


Getting titles from the test run:

Fetching all titles of the test cases from the desired test run.

  


public static List<String> gettingTitlesFromRun() { 
    initialization(); 
    Response getResponse = setCommonHeaders(). 
            get("get_run_cases/" + runID); 
    jsonResponse_getRunCases = getResponse.asString(); 
    JsonPath = new JsonPath(jsonResponse_getRunCases); 
    allTitlesfromRun = jsonPath.getList("tests.case.title"); 
    return allTitlesfromRun; 
} 


Getting ID for the desired title:

The ID of the test case will be returned based on test case titles. The user shall provide the test case title in the test cases, which should be the same title as the test cases that exist in Testworthy.

  

public static int getIdForDesiredTitle(String desiredTitle) { 
    if (allTitlesfromRun == null) { 
        gettingTitlesFromRun(); 
    } 
    JsonPath = new JsonPath(jsonResponse_getRunCases); 
    return jsonPath.getInt("tests.find " + 
            "{ " + 
            "it.case.title == '" + desiredTitle + "' " + 
            "}" + 
            ".case.id"); 
} 


Updating the test case results:

Test Run ID and Test Case ID are fetched previously, in this part test cases are marked either ‘Pass’ or ‘Fail’ based on the automated test case execution results.

  

public static void UpdateTestCaseResult(int case_id, int status) { 
 
    //loading the configuration and setting URL 
    initialization(); 
 
    //Getting the runID from SuitID on the basis of Run Name 
    runID = getRunIDfromSuiteID(); 
 
    JSONObject requestPayload = new JSONObject(); 
    JSONArray resultsArray = new JSONArray(); 
    JSONObject obj = new JSONObject(); 
    obj.put("case_id", case_id); 
    obj.put("status_id", status); 
    resultsArray.put(obj); 
    requestPayload.put("Results", resultsArray); 
    String requestBody = requestPayload.toString(); 
 
    Response postResponse = setCommonHeaders() 
            .body(requestBody) 
            .post("add_results_for_cases/" + runID); 
    postResponse.then().log().status(); 
} 

Sample test class:

Utilizing the APIs to mark the test cases of testworthy either pass or fail based on assertion.

  

public class LoginTest extends BaseTest { 
     protected int testCaseID; 

    @Test 
     public void loginUserVerifyTitle() { 
         String title = "User shall logged with valid credentials and title of the page shall be  Title"; 
         testCaseID = TestWorthyManager.getIdForDesiredTitle(title); 
         LoginPage loginPage = new LoginPage(driver); 
         loginPage.enterEmail(“email”); 
         loginPage.enterPassword("password"); 
         loginPage.clickLoginButton(); 
         String pageTitle = driver.getTitle(); 
         Assert.assertEquals(pageTitle, "Title", "Page title does not match. FAIL."); 

//This method will be called after each test cases to check either test is to be marked as Pass or Fail  
@AfterMethod 
    public void addResultToTestRun(ITestResult result) { 
        if (result.getStatus() == ITestResult.SUCCESS) { 
            TestWorthyManager.UpdateTestCaseResult(testCaseID, TestWorthyManager.passed); 
        } else if (result.getStatus() == ITestResult.FAILURE) { 
            TestWorthyManager.UpdateTestCaseResult(testCaseID, TestWorthyManager.failed); 
        } 
        if (driver != null) { 
            driver.quit(); 
        } 
    } 
}  

Playwright

Prerequisites:

  • Playwright with JavaScript
  • Testworthy account with access to the desired project
  • Testworthy API key (You can obtain this from your Testworthy account settings)

Obtaining Suite ID:

  • Open the Testworthy project in your browser.
  • Navigate to the desired Suite.
  • Obtain the suite ID from the URL. It should look like .../Project/Overview/suite_id.

Running the automation scripts:

Execute the following command in the terminal to run the Playwright (JavaScript) automation script:


npx playwright test 

Code snippets for the Playwright

Configuration:

This is the configuration file. All the required configuration needs to be added in Config.js.

  

module.exports = { 
    tw_Creds: { 
    baseAPIURL : 'www.testworthy.com', 
    suite_id : 'Project Suite Id', 
    run_title: 'Regression Cycle', 
    user_email : 'your_email@example.com', 
    tma_key : 'TestWorthy API key', 
    project_key : 'your_project_key', 
    cookies: 'Your user cookies' 
    }

}  

Testworthy_Methods.js

  1. Create a new file testworthy_methods.js
  2. Copy and paste the below code snippet
    • In this code, you can see a class testWorthyAPIs{}
    • Add the Testworthy Methods one by one in this class after constructor function
  

const apiData = require('Your_File_Path/config.js'); 
//This global array will store the Case Titles and Case IDs from "get_run_cases" API response 

let testCaseDataArray = []; 
// Global variable for assigning Test Case IDs to use in the tests 

let case_id; 
// Global variables to dynamically handle the run ids to use in a specific call 

let run_id; 
let run_title; 
class testWorthyAPIs{  
  constructor() { 
    // You can initialize any properties here 

  } 

  //*** Add Test Worthy methods from here ***// 

} 
module.exports = { testWorthyAPIs } 


Testworthy Methods:

Add the following methods in above testWorthyAPIs{} class.

1. Getting Run ID from Suite ID:

Suite ID is already mentioned in Configuration, Here with the help of Suite ID, Run ID is fetched.

  

    async get_run_from_suit_id() {
      const apiUrl = apiData.tw_Creds.baseAPIURL + "get_runs/" +
          apiData.tw_Creds.suite_id;
      process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
      const requestOptions = {
          method: 'GET',
          headers: {
              'X-USER-EMAIL': apiData.tw_Creds.user_email,
              'X-TMA-KEY': apiData.tw_Creds.tma_key,
              'X-PROJECT-KEY': apiData.tw_Creds.project_key,
              'Content-Type': 'application/json',
              'Cookie': apiData.tw_Creds.cookies,
          },
      };
      try {
          const response = await fetch(apiUrl, requestOptions);

          if (!response.ok) {
              throw new Error(`API request failed with status: ${response.status}`);
          }
          const data = await response.json();

          if (data.runs && data.runs.length > 0) {
              const runs = data.runs;
              const targetRunName = apiData.tw_Creds.run_title;
              const targetRun = runs.find(run => run.name === targetRunName);
              if (targetRun) {
                  console.log('Target Run Title is:', targetRun.name);
                  console.log('Target Run ID is:', targetRun.id);
                  run_id = targetRun.id;
                  run_title = targetRun.name;
                  console.log('Final Run ID:', run_id);
                  console.log('Final Run Title:', run_title);
                  return targetRun;
              } else {
                  console.log(`No run found with the name: ${targetRunName}`);
                  return null;
              }
          } else {
              console.log('No runs found in the response.');
              return null;
          }
          return data;
      } catch (error) {
          console.error('API Request Error:', error);
          throw error;
      }
  }


2. Getting ID for the desired title:

The ID of the test case will be returned based on test case titles. The user shall provide the test case title in the test cases, which should be the same title as the test cases that exist in Testworthy.

  


async get_case_id_api() {
    const apiUrl = apiData.tw_Creds.baseAPIURL + "get_run_cases/" +
        run_id;
    process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
    const requestOptions = {
        method: 'GET',
        headers: {
            'X-USER-EMAIL': apiData.tw_Creds.user_email,
            'X-TMA-KEY': apiData.tw_Creds.tma_key,
            'X-PROJECT-KEY': apiData.tw_Creds.project_key,
            'Content-Type': 'application/json',
            'Cookie': apiData.tw_Creds.cookies,
        },
    };
    try {
        const response = await fetch(apiUrl, requestOptions);
        if (!response.ok) {
            throw new Error(`API request failed with status: ${response.status}`);
        }
        const data = await response.json();
        const tests = data.tests;
        for (const test of tests) {
            const caseId = test.case.id;
            const caseTitle = test.case.title;
            testCaseDataArray.push({
                caseId,
                caseTitle
            });
        }
        console.log('Array Data', testCaseDataArray);
        return data;
    } catch (error) {
        console.error('API Request Error:', error);
        throw error;
    }
}


3. Matching Case ID for the desired title:

Matching the Test Case ID with the titles.

  

async matchAndAssignCaseId(currentTestTitle) {
    const matchingTest = testCaseDataArray.find(test => test.caseTitle === currentTestTitle);
    if (matchingTest) {
        case_id = matchingTest.caseId;
        console.log('Match found. Assigned caseId:', case_id);
    } else {
        console.error('No match found for the test title:', currentTestTitle);
    }
    console.log('Case ID: ', case_id);
    console.log('Case Title: ', matchingTest.caseTitle);
}


4. Updating the test case results:

Test Run ID and Test Case ID are fetched previously, in this part test cases are marked either ‘Pass’ or ‘Fail’ based on the automated test case execution results.

  

  async add_results_for_cases(testStatus) {
     if (testStatus === 'PASSED') {
         testStatus = 1;
         console.log('Test Status = ' + testStatus);
     } else {
         testStatus = 5
         console.log('Test Status = ' + testStatus);
     }
     const apiUrl = apiData.tw_Creds.baseAPIURL +
         "add_results_for_cases/" + run_id;
     process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
     console.log('Case ID in Map Status Function', case_id);
     const requestData = {
         "Results": [{
             "case_id": case_id,
             "status_id": testStatus,
             "Comment": "test from postman",
         }]
     }
     const requestOptions = {
         method: 'POST',
         headers: {
             'X-USER-EMAIL': apiData.tw_Creds.user_email,
             'X-TMA-KEY': apiData.tw_Creds.tma_key,
             'X-PROJECT-KEY': apiData.tw_Creds.project_key,
             'Content-Type': 'application/json',
             'Cookie': apiData.tw_Creds.cookies,
         },
         body: JSON.stringify(requestData),
     };

     try {
         const response = await fetch(apiUrl, requestOptions);
         if (!response.ok) {
             throw new Error(`API request failed with status: ${response.status}`);
         }
         const data = await response.json();
         console.log('API Response Data:', data);
         return data;
     } catch (error) {
         console.error('API Request Error:', error);
         throw error;
     }
 }

Playwright framework hierarchy:

Playright

Sample test code:

In this sample code, you can have an idea about how you can use the Testworthy test cases mapping methods in your test class.

There are 5 sections:

  1. Imports section: At the top, you can import all your page classes and Testworthy integration class
  2. Describe block: Inside this “describe” block you can implement your tests
  3. BeforeAll block: Inside “beforeAll”, you need to call two Testworthy integration methods
    • get_run_from_suit_id(); This method helps you to fetch the desired Test Run.
    • get_case_id_api(); This method helps you to fetch the test case Id and test case titles for the respective test run.
  4. AfterEach Block: Inside “afterEach” you need to call the method that will map test results on the Testworthy. It will be executed after each test.
    • add_results_for_cases(testStatus); This method maps the test results on Testworthy on the respective test run.
  5. Test Block: Inside “test” you can write your automated tests.

sampleTestClass.spec.js

  

import { test, expect, request } from '@playwright/test';
const { signUp } = require('../page/signupPageClass.js');
const { purchaseItem } = require('../page/samplePageClass.js');
const { testWorthyAPIs } = require('../TestWorthy-JS-Integration/testworthy-api-functions.js');

test.describe('Demo - TestWorthy Integration with Playwright/JavaScript', () => {
  let page;

  // Initialize the test status as 'FAILED'. Mandatory to have this as PlayWright doesn't have its own Test Status variable
  let testStatus = 'FAILED';

  // Object of Testworthy API Class
  const testWorthyAPIs_Obj = new testWorthyAPIs();

  // This is for random username and password generation, you can use your own mechanism for this
  const randomUsername = Math.random().toString(36).substring(2, 7);
  console.log(randomUsername);
  const randomPassword = Math.random().toString(36).substring(2, 7);
  console.log(randomPassword);

  test.beforeAll(async ({ browser }) => {
    // API - GET Runs via Suite ID
    // This API will fetch all the test runs using a specific suite id
    await testWorthyAPIs_Obj.get_run_from_suit_id();

    // API - Get Test Cases IDs
    // Call this method here in beforeAll to get all the Test Cases IDs and Titles present in the Test Run on TestWorthy before starting the execution of automated Test Cases. It will help in matching and assigning Test Case IDs to the relevant Automated Test Case
    await testWorthyAPIs_Obj.get_case_id_api();

    page = await browser.newPage();

    const userSignUp = new signUp(page);
    await userSignUp.gotoSite();
  });

  test.afterEach(async () => {
    // Call "add_results_for_cases" API function
    // Call this method in afterEach, so it will map the Automated Case status to the relevant test case in the TestWorthy. It has an argument "testStatus" globally initialized
    await testWorthyAPIs_Obj.add_results_for_cases(testStatus);
  });

  test('Case - 1: Verify use can sign up a new account', async () => {
    // Mandatory to have variable "currentTestTitle" in every test case and in the value copy and paste the same test case title you are going to Automate from the Test Run on the TestWorthy
    const currentTestTitle = 'Verify use can sign up a new account';

    // Call this method in every Test Case. It will match and assign the relevant test title from the Test Run on the TestWorthy. It has the argument "currentTestTitle" declared above
    await testWorthyAPIs_Obj.matchAndAssignCaseId(currentTestTitle);

    // Recommended to write Tests in Try Catch blocks so that it would be easy to assign the correct Test Status to the variable "testStatus" globally initialized and less chance to map the incorrect test statues on TestWorthy
    try {
      const userSignUp = new signUp(page);

      await userSignUp.signUpNewUser(randomUsername, randomPassword);
      await userSignUp.login(randomUsername, randomPassword);
      await expect(page.locator('#nameofuser')).toHaveText('Welcome ' + randomUsername);

      const welcomeName = await userSignUp.welcomeText.textContent();
      console.log('Welcome Name = ' + welcomeName);
      await expect(userSignUp.welcomeText).toHaveText(welcomeName);

      // If a failure condition is met, update the test status to 'FAILED'
      if (await welcomeName != 'Welcome ' + randomUsername) {
        console.log('welcomeName =' + welcomeName);
        testStatus = 'FAILED';
      } else {
        console.log('welcomeName =' + welcomeName);
        testStatus = 'PASSED';
      }
    } catch (error) {
      // Handle test failure (e.g., an unhandled exception) and update the status
      testStatus = 'FAILED';
      console.error('Test Error:', error);
    } finally {
      console.log('Test Status = ' + testStatus);
    }
  });



Note:

For any issues or questions, please contact support@testworthy.com