├── .eslintrc.js ├── .gitignore ├── .travis.yml ├── README.md ├── index.d.ts ├── index.js ├── package.json └── test ├── case_fields.js ├── case_types.js ├── cases.js ├── configs.js ├── milestones.js ├── plans.js ├── priorities.js ├── projects.js ├── result_fields.js ├── results.js ├── runs.js ├── sections.js ├── statuses.js ├── suites.js ├── templates.js ├── tests.js └── users.js /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "env": { 3 | "es6": true, 4 | "node": true 5 | }, 6 | "parserOptions": { 7 | "ecmaVersion": 5, 8 | }, 9 | "extends": "eslint:recommended", 10 | "rules": { 11 | "indent": [ 12 | "error", 13 | 2 14 | ], 15 | "linebreak-style": [ 16 | "error", 17 | "unix" 18 | ], 19 | "quotes": [ 20 | "error", 21 | "single" 22 | ], 23 | "semi": [ 24 | "error", 25 | "always" 26 | ] 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | coverage 4 | .idea/ 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4.0" 4 | - "5.0" 5 | - "5.6" 6 | - "5.11" 7 | - "6.2" 8 | script: npm run travis 9 | after_success: 'npm run coveralls' 10 | sudo: false -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # testrail-api 2 | 3 | [![npm version](https://badge.fury.io/js/testrail-api.svg)](http://badge.fury.io/js/testrail-api) 4 | [![Travis](https://travis-ci.org/rundef/node-testrail-api.svg?branch=master)](https://travis-ci.org/rundef/node-testrail-api?branch=master) 5 | [![Coverage Status](https://coveralls.io/repos/github/rundef/node-testrail-api/badge.svg?branch=master)](https://coveralls.io/github/rundef/node-testrail-api?branch=master) 6 | 7 | > An API wrapper for TestRail with error handling and unit testing. 8 | 9 | The TestRail API is [described here](http://docs.gurock.com/testrail-api2/start). 10 | 11 | ## Usage 12 | 13 | First, you will have to initialize the API wrapper : 14 | 15 | ```javascript 16 | var Testrail = require('testrail-api'); 17 | 18 | var testrail = new Testrail({ 19 | host: 'https://rundef.testrail.com', 20 | user: 'username', 21 | password: 'password or api key' 22 | }); 23 | ``` 24 | 25 | ## Callback 26 | 27 | Working with callbacks gives you three parameters: `error`, `response` and `body` in this order 28 | ```javascript 29 | function (err, response, body) 30 | ``` 31 | `error` is null when nothing unexpected happened. 32 | 33 | `response` contains data like the status code. 34 | 35 | `body` contains the response body the server sent back. 36 | 37 | ## Promises 38 | 39 | Working with Promises gives you `response` and `body` like this 40 | ```javascript 41 | .then(function (result) { 42 | console.log(result.response); 43 | console.log(result.body); 44 | }) 45 | .catch(function (error) { 46 | console.log(error.response); 47 | console.log(error.message); 48 | }); 49 | ``` 50 | 51 | ### Cases 52 | 53 | > List cases 54 | 55 | ```javascript 56 | testrail.getCases(/*PROJECT_ID=*/1, /*FILTERS=*/{ suite_id: 3, section_id: 4 }, function (err, response, cases) { 57 | console.log(cases); 58 | }); 59 | ``` 60 | 61 | You can also use Promises with all the functions: 62 | 63 | ```javascript 64 | testrail.getCases(1) 65 | .then(function (result) { 66 | console.log(result.body); 67 | }).catch(function (error) { 68 | console.log('error', error.message); 69 | }); 70 | ``` 71 | 72 | > Get a case 73 | 74 | ```javascript 75 | testrail.getCase(/*CASE_ID=*/1, function (err, response, testcase) { 76 | console.log(testcase); 77 | }); 78 | ``` 79 | 80 | > Add a case 81 | 82 | ```javascript 83 | testrail.addCase(/*SECTION_ID=*/1, /*CONTENT=*/{}, function (err, response, testcase) { 84 | console.log(testcase); 85 | }); 86 | ``` 87 | 88 | > Update a case 89 | 90 | ```javascript 91 | testrail.updateCase(/*CASE_ID=*/1, /*CONTENT=*/{}, function (err, response, testcase) { 92 | console.log(testcase); 93 | }); 94 | ``` 95 | 96 | > Delete a case 97 | 98 | ```javascript 99 | testrail.deleteCase(/*CASE_ID=*/1, function (err, response, body) { 100 | console.log(body); 101 | }); 102 | ``` 103 | 104 | ### Case Fields 105 | 106 | > List case fields 107 | 108 | ```javascript 109 | testrail.getCaseFields(function (err, response, caseFields) { 110 | console.log(caseFields); 111 | }); 112 | ``` 113 | 114 | ### Case Types 115 | 116 | > List case types 117 | 118 | ```javascript 119 | testrail.getCaseTypes(function (err, response, caseTypes) { 120 | console.log(caseTypes); 121 | }); 122 | ``` 123 | 124 | ### Configurations 125 | 126 | > List configurations 127 | 128 | ```javascript 129 | testrail.getConfigs(/*PROJECT_ID=*/1, function (err, response, configs) { 130 | console.log(configs); 131 | }); 132 | ``` 133 | 134 | > Add a configuration group 135 | 136 | ```javascript 137 | testrail.addConfigGroup(/*PROJECT_ID=*/1, /*CONTENT=*/{}, function (err, response, config_group) { 138 | console.log(config_group); 139 | }); 140 | ``` 141 | 142 | > Add a configuration 143 | 144 | ```javascript 145 | testrail.addConfig(/*CONFIGURATION_GROUP_ID=*/1, /*CONTENT=*/{}, function (err, response, config) { 146 | console.log(config); 147 | }); 148 | ``` 149 | 150 | > Update a configuration group 151 | 152 | ```javascript 153 | testrail.updateConfigGroup(/*CONFIGURATION_GROUP_ID=*/1, /*CONTENT=*/{}, function (err, response, config_group) { 154 | console.log(config_group); 155 | }); 156 | ``` 157 | 158 | > Update a configuration 159 | 160 | ```javascript 161 | testrail.updateConfig(/*CONFIGURATION_ID=*/1, /*CONTENT=*/{}, function (err, response, config) { 162 | console.log(config); 163 | }); 164 | ``` 165 | 166 | > Delete a configuration group 167 | 168 | ```javascript 169 | testrail.deleteConfigurationGroup(/*CONFIGURATION_GROUP_ID=*/1, function (err, response, body) { 170 | console.log(body); 171 | }); 172 | ``` 173 | 174 | > Delete a configuration 175 | 176 | ```javascript 177 | testrail.deleteConfig(/*CONFIGURATION_ID=*/1, function (err, response, body) { 178 | console.log(body); 179 | }); 180 | ``` 181 | 182 | ### Milestones 183 | 184 | > List milestones 185 | 186 | ```javascript 187 | testrail.getMilestones(/*PROJECT_ID=*/1, /*FILTERS=*/{}, function (err, response, milestones) { 188 | console.log(milestones); 189 | }); 190 | ``` 191 | 192 | > Get a milestone 193 | 194 | ```javascript 195 | testrail.getMilestone(/*MILESTONE_ID=*/1, function (err, response, milestone) { 196 | console.log(milestone); 197 | }); 198 | ``` 199 | 200 | > Add a milestone 201 | 202 | ```javascript 203 | testrail.addMilestone(/*PROJECT_ID=*/1, /*CONTENT=*/{}, function (err, response, milestone) { 204 | console.log(milestone); 205 | }); 206 | ``` 207 | 208 | > Update a milestone 209 | 210 | ```javascript 211 | testrail.updateMilestone(/*MILESTONE_ID=*/1, /*CONTENT=*/{}, function (err, response, milestone) { 212 | console.log(milestone); 213 | }); 214 | ``` 215 | 216 | > Delete a milestone 217 | 218 | ```javascript 219 | testrail.deleteMilestone(/*MILESTONE_ID=*/1, function (err, response, body) { 220 | console.log(body); 221 | }); 222 | ``` 223 | 224 | ### Plans 225 | 226 | > List plans 227 | 228 | ```javascript 229 | testrail.getPlans(/*PROJECT_ID=*/1, /*FILTERS=*/{}, function (err, response, plans) { 230 | console.log(plans); 231 | }); 232 | ``` 233 | 234 | > Get a plan 235 | 236 | ```javascript 237 | testrail.getPlan(/*PLAN_ID=*/1, function (err, response, plan) { 238 | console.log(plan); 239 | }); 240 | ``` 241 | 242 | > Add a plan 243 | 244 | ```javascript 245 | testrail.addPlan(/*PROJECT_ID=*/1, /*CONTENT=*/{}, function (err, response, plan) { 246 | console.log(plan); 247 | }); 248 | ``` 249 | 250 | > Add a plan entry 251 | 252 | ```javascript 253 | testrail.addPlanEntry(/*PLAN_ID=*/1, /*CONTENT=*/{}, function (err, response, plan_entry) { 254 | console.log(plan_entry); 255 | }); 256 | ``` 257 | 258 | > Update a plan 259 | 260 | ```javascript 261 | testrail.updatePlan(/*PLAN_ID=*/1, /*CONTENT=*/{}, function (err, response, plan) { 262 | console.log(plan); 263 | }); 264 | ``` 265 | 266 | > Update a plan entry 267 | 268 | ```javascript 269 | testrail.updatePlanEntry(/*PLAN_ID=*/1, /*PLAN_ENTRY_ID=*/2, /*CONTENT=*/{}, function (err, response, plan_entry) { 270 | console.log(plan_entry); 271 | }); 272 | ``` 273 | 274 | > Close a plan 275 | 276 | ```javascript 277 | testrail.closePlan(/*PLAN_ID=*/1, function (err, response, plan) { 278 | console.log(plan); 279 | }); 280 | ``` 281 | 282 | > Delete a plan 283 | 284 | ```javascript 285 | testrail.deletePlan(/*PLAN_ID=*/1, function (err, response, body) { 286 | console.log(body); 287 | }); 288 | ``` 289 | 290 | > Delete a plan entry 291 | 292 | ```javascript 293 | testrail.deletePlanEntry(/*PLAN_ID=*/1, /*PLAN_ENTRY_ID=*/2, function (err, response, body) { 294 | console.log(body); 295 | }); 296 | ``` 297 | 298 | ### Priorities 299 | 300 | ```javascript 301 | testrail.getPriorities(function (err, response, priorities) { 302 | console.log(priorities); 303 | }); 304 | ``` 305 | 306 | ### Projects 307 | 308 | > List projects 309 | 310 | ```javascript 311 | testrail.getProjects(/*FILTERS=*/{}, function (err, response, projects) { 312 | console.log(projects); 313 | }); 314 | ``` 315 | 316 | > Get a project 317 | 318 | ```javascript 319 | testrail.getProject(/*PROJECT_ID=*/1, function (err, response, project) { 320 | console.log(project); 321 | }); 322 | ``` 323 | 324 | > Add a project 325 | 326 | ```javascript 327 | testrail.addProject(/*CONTENT=*/{}, function (err, response, project) { 328 | console.log(project); 329 | }); 330 | ``` 331 | 332 | > Update a project 333 | 334 | ```javascript 335 | testrail.updateProject(/*PROJECT_ID=*/1, /*CONTENT=*/{}, function (err, response, project) { 336 | console.log(project); 337 | }); 338 | ``` 339 | 340 | > Delete a project 341 | 342 | ```javascript 343 | testrail.deleteProject(/*PROJECT_ID=*/1, function (err, response, body) { 344 | console.log(body); 345 | }); 346 | ``` 347 | 348 | ### Results 349 | 350 | > Get results 351 | 352 | ```javascript 353 | testrail.getResults(/*TEST_ID=*/1, /*FILTERS=*/{}, function (err, response, results) { 354 | console.log(results); 355 | }); 356 | ``` 357 | 358 | > Get results for case 359 | 360 | ```javascript 361 | testrail.getResultsForCase(/*RUN_ID=*/1, /*CASE_ID=*/2, /*FILTERS=*/{}, function (err, response, results) { 362 | console.log(results); 363 | }); 364 | ``` 365 | 366 | > Get results for run 367 | 368 | ```javascript 369 | testrail.getResultsForRun(/*RUN_ID=*/1, /*FILTERS=*/{}, function (err, response, results) { 370 | console.log(results); 371 | }); 372 | ``` 373 | 374 | > Add a result 375 | 376 | ```javascript 377 | testrail.addResult(/*TEST_ID=*/1, /*CONTENT=*/{}, function (err, response, result) { 378 | console.log(result); 379 | }); 380 | ``` 381 | 382 | > Add a result for case 383 | 384 | ```javascript 385 | testrail.addResultForCase(/*RUN_ID=*/1, /*CASE_ID=*/2, /*CONTENT=*/{}, function (err, response, result) { 386 | console.log(result); 387 | }); 388 | ``` 389 | 390 | > Add results 391 | 392 | ```javascript 393 | testrail.addResults(/*RUN_ID=*/1, /*CONTENT=*/{}, function (err, response, results) { 394 | console.log(results); 395 | }); 396 | ``` 397 | 398 | > Add results for cases 399 | 400 | ```javascript 401 | testrail.addResultsForCases(/*RUN_ID=*/1, /*CONTENT=*/{}, function (err, response, results) { 402 | console.log(results); 403 | }); 404 | ``` 405 | 406 | ### Result Fields 407 | 408 | ```javascript 409 | testrail.getResultFields(function (err, response, resultFields) { 410 | console.log(resultFields); 411 | }); 412 | ``` 413 | 414 | ### Runs 415 | 416 | > List runs 417 | 418 | ```javascript 419 | testrail.getRuns(/*PROJECT_ID=*/1, /*FILTERS=*/{}, function (err, response, runs) { 420 | console.log(runs); 421 | }); 422 | ``` 423 | 424 | > Get a run 425 | 426 | ```javascript 427 | testrail.getRun(/*RUN_ID=*/1, function (err, response, run) { 428 | console.log(run); 429 | }); 430 | ``` 431 | 432 | > Add a run 433 | 434 | ```javascript 435 | testrail.addRun(/*PROJECT_ID=*/1, /*CONTENT=*/{}, function (err, response, run) { 436 | console.log(run); 437 | }); 438 | ``` 439 | 440 | > Update a run 441 | 442 | ```javascript 443 | testrail.updateRun(/*RUN_ID=*/1, /*CONTENT=*/{}, function (err, response, run) { 444 | console.log(run); 445 | }); 446 | ``` 447 | 448 | > Close a run 449 | 450 | ```javascript 451 | testrail.closeRun(/*RUN_ID=*/1, function (err, response, run) { 452 | console.log(run); 453 | }); 454 | ``` 455 | 456 | > Delete a run 457 | 458 | ```javascript 459 | testrail.deleteRun(/*RUN_ID=*/1, function (err, response, body) { 460 | console.log(body); 461 | }); 462 | ``` 463 | 464 | ### Sections 465 | 466 | > List sections 467 | 468 | ```javascript 469 | testrail.getSections(/*PROJECT_ID=*/1, /*FILTERS=*/{}, function (err, response, sections) { 470 | console.log(sections); 471 | }); 472 | ``` 473 | 474 | > Get a section 475 | 476 | ```javascript 477 | testrail.getSection(/*SECTION_ID=*/1, function (err, response, section) { 478 | console.log(section); 479 | }); 480 | ``` 481 | 482 | > Add a section 483 | 484 | ```javascript 485 | testrail.addSection(/*PROJECT_ID=*/1, /*CONTENT=*/{}, function (err, response, section) { 486 | console.log(section); 487 | }); 488 | ``` 489 | 490 | > Update a section 491 | 492 | ```javascript 493 | testrail.updateSection(/*SECTION_ID=*/1, /*CONTENT=*/{}, function (err, response, section) { 494 | console.log(section); 495 | }); 496 | ``` 497 | 498 | > Delete a section 499 | 500 | ```javascript 501 | testrail.deleteSection(/*SECTION_ID=*/1, function (err, response, body) { 502 | console.log(body); 503 | }); 504 | ``` 505 | 506 | ### Statuses 507 | 508 | ```javascript 509 | testrail.getStatuses(function (err, response, statuses) { 510 | console.log(statuses); 511 | }); 512 | ``` 513 | 514 | ### Suites 515 | 516 | > List suites 517 | 518 | ```javascript 519 | testrail.getSuites(/*PROJECT_ID=*/1, function (err, response, suites) { 520 | console.log(suites); 521 | }); 522 | ``` 523 | 524 | > Get a suite 525 | 526 | ```javascript 527 | testrail.getSuite(/*SUITE_ID=*/1, function (err, response, suite) { 528 | console.log(suite); 529 | }); 530 | ``` 531 | 532 | > Add a suite 533 | 534 | ```javascript 535 | testrail.addSuite(/*PROJECT_ID=*/1, /*CONTENT=*/{}, function (err, response, suite) { 536 | console.log(suite); 537 | }); 538 | ``` 539 | 540 | > Update a suite 541 | 542 | ```javascript 543 | testrail.updateSuite(/*SUITE_ID=*/1, /*CONTENT=*/{}, function (err, response, suite) { 544 | console.log(suite); 545 | }); 546 | ``` 547 | 548 | > Delete a suite 549 | 550 | ```javascript 551 | testrail.deleteSuite(/*SUITE_ID=*/1, function (err, response, body) { 552 | console.log(body); 553 | }); 554 | ``` 555 | 556 | ### Templates 557 | 558 | ```javascript 559 | testrail.getTemplates(/*PROJECT_ID=*/1, function (err, response, template) { 560 | console.log(template); 561 | }); 562 | ``` 563 | 564 | ### Tests 565 | 566 | > List tests 567 | 568 | ```javascript 569 | testrail.getTests(/*RUN_ID=*/1, /*FILTERS=*/{}, function (err, response, tests) { 570 | console.log(tests); 571 | }); 572 | ``` 573 | 574 | > Get a test 575 | 576 | ```javascript 577 | testrail.getTest(/*TEST_ID=*/1, function (err, response, test) { 578 | console.log(test); 579 | }); 580 | ``` 581 | 582 | ### Users 583 | 584 | > List users 585 | 586 | ```javascript 587 | testrail.getUsers(/*FILTERS=*/{}, function (err, response, users) { 588 | console.log(users); 589 | }); 590 | ``` 591 | 592 | > Get a user 593 | 594 | ```javascript 595 | testrail.getUser(/*USER_ID=*/1, function (err, response, user) { 596 | console.log(user); 597 | }); 598 | ``` 599 | 600 | > Get a user by email 601 | 602 | ```javascript 603 | testrail.getUserByEmail(/*EMAIL=*/'test@gmail.com', function (err, response, user) { 604 | console.log(user); 605 | }); 606 | ``` 607 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | import t = TestrailApiClient; 2 | import { Response } from 'request' 3 | 4 | declare class TestrailApiClient { 5 | constructor(options: {host: string, user: string, password: string}); 6 | 7 | getCase(id: number, callback?: t.Callback): t.PromiseResponse; 8 | getCases(project_id: number, filters?: t.ICaseFilters, callback?: t.Callback): t.PromiseResponse; 9 | addCase(section_id: number, data: T, callback?: t.Callback): t.PromiseResponse; 10 | updateCase(case_id: number, data: T, callback?: t.Callback): t.PromiseResponse; 11 | deleteCase(case_id: number, callback?: t.Callback): t.PromiseResponse; 12 | 13 | getCaseFields(callback?: t.Callback): t.PromiseResponse; 14 | getCaseTypes(callback?: t.Callback): t.PromiseResponse; 15 | 16 | getConfigs(project_id: number, callback?: t.Callback): t.PromiseResponse; 17 | addConfigGroup(project_id: number, data: t.IConfigurationUpdate, callback?: t.Callback): t.PromiseResponse; 18 | addConfig(config_group_id: number, data: t.IConfigurationUpdate, callback?: t.Callback): t.PromiseResponse; 19 | updateConfigGroup(config_group_id: number, data: t.IConfigurationUpdate, callback?: t.Callback): t.PromiseResponse; 20 | updateConfig(config_id: number, data: t.IConfigurationUpdate, callback?: t.Callback): t.PromiseResponse; 21 | deleteConfigGroup(config_group_id: number, callback?: t.Callback): t.PromiseResponse; 22 | deleteConfig(config_id: number, callback?: t.Callback): t.PromiseResponse; 23 | 24 | getMilestone(id: number, callback?: t.Callback): t.PromiseResponse; 25 | getMilestones(project_id: number, filters?: t.IMilestoneFilters, callback?: t.Callback): t.PromiseResponse; 26 | addMilestone(project_id: number, data: t.INewMilestone, callback?: t.Callback): t.PromiseResponse; 27 | updateMilestone(milestone_id: number, data: t.IMilestoneUpdate, callback?: t.Callback): t.PromiseResponse; 28 | deleteMilestone(milestone_id: number, callback?: t.Callback): t.PromiseResponse; 29 | 30 | getPlan(id: number, callback?: t.Callback): t.PromiseResponse; 31 | getPlans(project_id: number, filters?: any, callback?: t.Callback): t.PromiseResponse; 32 | addPlan(project_id: number, data: any, callback?: t.Callback): t.PromiseResponse; 33 | addPlanEntry(plan_id: number, data: any, callback?: t.Callback): t.PromiseResponse; 34 | updatePlan(plan_id: number, data: any, callback?: t.Callback): t.PromiseResponse; 35 | updatePlanEntry(plan_id: number, entry_id: number, data: any, callback?: t.Callback): t.PromiseResponse; 36 | closePlan(plan_id: number, callback?: t.Callback): t.PromiseResponse; 37 | deletePlan(plan_id: number, callback?: t.Callback): t.PromiseResponse; 38 | deletePlanEntry(plan_id: number, entry_id: number, callback?: t.Callback): t.PromiseResponse; 39 | 40 | getPriorities(callback?: t.Callback): t.PromiseResponse; 41 | 42 | getProject(id: number, callback?: t.Callback): t.PromiseResponse; 43 | getProjects(filters?: t.IProjectFilters, callback?: t.Callback): t.PromiseResponse; 44 | addProject(data: t.IProjectUpdate, callback?: t.Callback): t.PromiseResponse; 45 | updateProject(project_id: number, data: t.IProjectUpdate, callback?: t.Callback): t.PromiseResponse; 46 | deleteProject(project_id: number, callback?: t.Callback): t.PromiseResponse; 47 | 48 | getResults(test_id: number, filters?: t.ITestResultFilters, callback?: t.Callback): t.PromiseResponse; 49 | getResultsForCase(run_id: number, case_id: number, filters?: t.ITestResultFilters, callback?: t.Callback): t.PromiseResponse; 50 | getResultsForRun(run_id: number, filters?: t.ITestResultsForRunFilters, callback?: t.Callback): t.PromiseResponse; 51 | addResult(test_id: number, data: T, callback?: t.Callback): t.PromiseResponse; 52 | addResultForCase(run_id: number, case_id: number, data: t.INewTestResult, callback?: t.Callback): t.PromiseResponse; 53 | addResults(run_id: number, data: T[], callback?: t.Callback): t.PromiseResponse; 54 | addResultsForCases(run_id: number, data: T[], callback?: t.Callback): t.PromiseResponse; 55 | getResultFields(callback?: t.Callback): t.PromiseResponse; 56 | 57 | getRun(id: number, callback?: t.Callback): t.PromiseResponse; 58 | getRuns(project_id: number, filters?: any, callback?: t.Callback): t.PromiseResponse; 59 | addRun(project_id: number, data: t.INewTestRun, callback?: t.Callback): t.PromiseResponse; 60 | updateRun(run_id: number, data: t.INewTestRun, callback?: t.Callback): t.PromiseResponse; 61 | closeRun(run_id: number, callback?: t.Callback): t.PromiseResponse; 62 | deleteRun(run_id: number, callback?: t.Callback): t.PromiseResponse; 63 | 64 | getSection(id: number, callback?: t.Callback): t.PromiseResponse; 65 | getSections(project_id: number, filters?: any, callback?: t.Callback): t.PromiseResponse; 66 | addSection(project_id: number, data: t.INewSection, callback?: t.Callback): t.PromiseResponse; 67 | updateSection(section_id: number, data: t.ISectionUpdate, callback?: t.Callback): t.PromiseResponse; 68 | deleteSection(section_id: number, callback?: t.Callback): t.PromiseResponse; 69 | 70 | getStatuses(callback?: t.Callback): t.PromiseResponse; 71 | 72 | getSuite(id: number, callback?: t.Callback): t.PromiseResponse; 73 | getSuites(project_id: number, callback?: t.Callback): t.PromiseResponse; 74 | addSuite(project_id: number, data: t.INewSuite, callback?: t.Callback): t.PromiseResponse; 75 | updateSuite(suite_id: number, data: t.INewSuite, callback?: t.Callback): t.PromiseResponse; 76 | deleteSuite(suite_id: number, callback?: t.Callback): t.PromiseResponse; 77 | 78 | getTemplates(project_id: number, callback?: t.Callback): t.PromiseResponse; 79 | 80 | getTest(id: number, callback?: t.Callback): t.PromiseResponse; 81 | getTests(run_id: number, filters: { status_id?: number | number[] }, callback?: t.Callback): t.PromiseResponse; 82 | 83 | getUser(id: number, callback?: t.Callback): t.PromiseResponse; 84 | getUserByEmail(email: string, callback?: t.Callback): t.PromiseResponse; 85 | getUsers(callback?: t.Callback): t.PromiseResponse; 86 | } 87 | 88 | declare namespace TestrailApiClient { 89 | type CustomFieldType = boolean | string | number | number[] | any[] | undefined; 90 | 91 | type PromiseResponse = Promise<{ response: Response, body: T }> 92 | 93 | interface ITestResult { 94 | assignedto_id: number; 95 | comment: string; 96 | created_by: number; 97 | created_on: number; 98 | defects: string; 99 | elapsed: string; 100 | id: number; 101 | status_id: number; 102 | test_id: number; 103 | version: string; 104 | 105 | [key: string]: CustomFieldType; 106 | } 107 | 108 | interface INewTestResult { 109 | status_id: number; 110 | comment?: string; 111 | version?: string; 112 | elapsed?: string; 113 | defects?: string; 114 | assignedto_id?: number; 115 | 116 | [key: string]: CustomFieldType; 117 | } 118 | 119 | interface INewTestResults{ 120 | results: T[]; 121 | } 122 | 123 | interface ITest { 124 | id: number; 125 | case_id: number; 126 | assignedto_id?: number; 127 | estimate?: string; 128 | estimate_forecast?: string; 129 | milestone_id?: number; 130 | priority_id?: number; 131 | refs?: string; 132 | run_id?: number; 133 | status_id?: number; 134 | title?: string; 135 | type_id?: number; 136 | 137 | [key: string]: CustomFieldType; 138 | } 139 | 140 | interface ICase { 141 | created_by?: number; 142 | created_on?: number; 143 | estimate?: any; 144 | estimate_forecast?: any; 145 | id?: number; 146 | milestone_id?: number; 147 | priority_id?: number; 148 | refs?: string; 149 | section_id?: number; 150 | suite_id?: number; 151 | template_id?: number; 152 | title?: string; 153 | type_id?: number; 154 | updated_by?: number; 155 | updated_on?: number; 156 | 157 | [key: string]: CustomFieldType; 158 | } 159 | 160 | interface ICaseField { 161 | description: string; 162 | display_order?: number; 163 | id: number; 164 | include_all?: boolean; 165 | is_active?: boolean; 166 | label?: string; 167 | name: string; 168 | system_name: string; 169 | template_ids?: number[]; 170 | type_id: number; 171 | configs?: ICaseFieldConfig[]; 172 | } 173 | 174 | interface ICaseType { 175 | id: number; 176 | is_default: boolean; 177 | name: string; 178 | } 179 | 180 | interface ICaseFieldConfig { 181 | id: string; 182 | context: { 183 | is_global?: boolean; 184 | project_ids: number[]; 185 | }; 186 | options: { 187 | items?: string; 188 | default_value?: string; 189 | format?: string; 190 | is_required?: boolean; 191 | has_actual?: boolean; 192 | has_expected?: boolean; 193 | rows?: string; 194 | }; 195 | } 196 | 197 | interface ISection { 198 | depth: number; 199 | description: string; 200 | display_order: number; 201 | id: number; 202 | name: string; 203 | parent_id: number; 204 | suite_id: number; 205 | } 206 | 207 | interface ISectionUpdate { 208 | description?: string; 209 | name?: string; 210 | } 211 | 212 | interface INewSection { 213 | description?: string; 214 | suite_id: number; 215 | parent_id: number; 216 | name: string; 217 | } 218 | 219 | interface ICaseUpdate { 220 | title?: string; 221 | template_id?: number; 222 | type_id?: number; 223 | priority_id?: number; 224 | estimate?: string; 225 | milestone_id?: number; 226 | refs?: string; 227 | 228 | [key: string]: CustomFieldType; 229 | } 230 | 231 | interface ICaseFilters { 232 | suite_id?: number; 233 | section_id?: number; 234 | created_after?: number; 235 | created_before?: number; 236 | created_by?: string; 237 | milestone_id?: number; 238 | priority_id?: number; 239 | template_id?: number; 240 | type_id?: number; 241 | updated_after?: number; 242 | updated_before?: number; 243 | updated_by?: number; 244 | } 245 | 246 | interface ITestrailUser { 247 | id: number; 248 | email: string; 249 | name: string; 250 | is_active: boolean; 251 | } 252 | 253 | interface ITemplate { 254 | id: number; 255 | is_default: boolean; 256 | name: string; 257 | } 258 | 259 | interface INewSuite { 260 | name?: string; 261 | description?: string; 262 | } 263 | 264 | interface ISuite { 265 | completed_on?: number; 266 | description: string; 267 | id: number; 268 | is_baseline?: boolean; 269 | is_completed?: boolean; 270 | is_master?: boolean; 271 | name: string; 272 | project_id: number; 273 | url: string; 274 | } 275 | 276 | interface ITestStatus { 277 | color_bright: string; 278 | color_dark: string; 279 | color_medium: string; 280 | id: number; 281 | is_final: boolean; 282 | is_system: boolean; 283 | is_untested: boolean; 284 | label: string; 285 | name: string; 286 | } 287 | 288 | interface ITestRun { 289 | assignedto_id: number; 290 | blocked_count: number; 291 | completed_on: number; 292 | config: string; 293 | config_ids: number[]; 294 | created_by: number; 295 | created_on: number; 296 | custom_status1_count: number; 297 | custom_status2_count: number; 298 | custom_status3_count: number; 299 | custom_status4_count: number; 300 | custom_status5_count: number; 301 | custom_status6_count: number; 302 | custom_status7_count: number; 303 | description: string; 304 | failed_count: number; 305 | id: number; 306 | include_all: boolean; 307 | is_completed: number; 308 | milestone_id: number; 309 | plan_id: number; 310 | name: string; 311 | passed_count: number; 312 | project_id: number; 313 | retest_count: number; 314 | suite_id: number; 315 | untested_count: number; 316 | url: string; 317 | } 318 | 319 | interface INewTestRun { 320 | suite_id: number; 321 | name: string; 322 | description: string; 323 | milestone_id: number; 324 | assignedto_id: number; 325 | include_all: boolean; 326 | case_ids: number[]; 327 | } 328 | 329 | interface ITestResultFilters { 330 | limit: number; 331 | offset: number; 332 | status_id: number | number[]; 333 | } 334 | 335 | interface ITestResultsForRunFilters extends ITestResultFilters { 336 | created_after: number; 337 | created_before: number; 338 | created_by: number | number[]; 339 | } 340 | 341 | interface IProject { 342 | announcment: string; 343 | completed_on: number; 344 | id: number; 345 | is_completed: number; 346 | name: string; 347 | show_announcement: boolean; 348 | suite_mode: SuiteMode; 349 | url: string; 350 | } 351 | 352 | interface IProjectUpdate { 353 | name?: string; 354 | announcement?: string; 355 | show_announcement?: boolean; 356 | suite_mode?: SuiteMode; 357 | is_completed?: boolean; 358 | } 359 | 360 | enum SuiteMode { 361 | SINGLE = 1, 362 | SINGLE_WITH_BASELINES, 363 | MULTIPLE_SUITES 364 | } 365 | 366 | interface IProjectFilters { 367 | is_completed: number; 368 | } 369 | 370 | interface IPriority { 371 | id: number; 372 | is_default: boolean; 373 | priority: number; 374 | short_name: string; 375 | name: string; 376 | } 377 | 378 | interface IMilestone { 379 | completed_on: number; 380 | description: string; 381 | due_on: number; 382 | id: number; 383 | is_completed: number; 384 | is_started: number; 385 | milestones?: IMilestone[]; 386 | name: string; 387 | parent_id: number; 388 | project_id: number; 389 | start_on: number; 390 | started_on: number; 391 | url: string; 392 | } 393 | 394 | interface INewMilestone { 395 | name?: string; 396 | description?: string; 397 | due_on?: number; 398 | parent_id?: number; 399 | start_on?: number; 400 | } 401 | 402 | interface IMilestoneUpdate extends INewMilestone { 403 | is_completed?: number; 404 | is_started?: number; 405 | } 406 | 407 | interface IMilestoneFilters { 408 | is_completed: number; 409 | is_started: number; 410 | } 411 | 412 | interface IConfigurationGroup { 413 | id: number; 414 | project_id: number; 415 | name: string; 416 | configs: IConfiguration[]; 417 | } 418 | 419 | interface IConfiguration { 420 | id: number; 421 | group_id: number; 422 | name: string; 423 | } 424 | 425 | interface IConfigurationUpdate { 426 | name: string; 427 | } 428 | 429 | interface Callback { 430 | (error: any, response: Response, result: T): void; 431 | } 432 | } 433 | 434 | export = TestrailApiClient; 435 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var request = require('request'); 2 | var qs = require('querystring'); 3 | var Promise = require('bluebird'); 4 | 5 | 6 | // ----- API Reference: http://docs.gurock.com/testrail-api2/start ----- 7 | 8 | function TestRail(options) { 9 | this.host = options.host; 10 | this.user = options.user; 11 | this.password = options.password; 12 | 13 | this.uri = '/index.php?/api/v2/'; 14 | } 15 | 16 | TestRail.prototype.apiGet = function (apiMethod, queryVariables, callback) { 17 | var url = this.host + this.uri + apiMethod; 18 | 19 | if(typeof queryVariables == 'function') { 20 | callback = queryVariables; 21 | queryVariables = null; 22 | } 23 | 24 | return this._callAPI('get', url, queryVariables, null, callback); 25 | }; 26 | 27 | TestRail.prototype.apiPost = function (apiMethod, body, queryVariables, callback) { 28 | var url = this.host + this.uri + apiMethod; 29 | 30 | if(typeof body == 'function') { 31 | callback = body; 32 | queryVariables = body = null; 33 | } 34 | else if(typeof queryVariables == 'function') { 35 | callback = queryVariables; 36 | queryVariables = null; 37 | } 38 | 39 | return this._callAPI('post', url, queryVariables, body, callback); 40 | }; 41 | 42 | TestRail.prototype._callAPI = function (method, url, queryVariables, body, callback) { 43 | if(queryVariables != null) { 44 | url += '&' + qs.stringify(queryVariables); 45 | } 46 | 47 | var requestArguments = { 48 | rejectUnauthorized: false, //added this line to solve Error: unable to verify the first certificate] code: 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' 49 | uri: url, 50 | headers: { 51 | 'content-type': 'application/json', 52 | 'accept': 'application/json' 53 | }, 54 | rejectUnauthorized: false 55 | }; 56 | 57 | if(body != null) { 58 | requestArguments.body = body; 59 | } 60 | 61 | if (typeof callback === 'function') { 62 | return request[method](requestArguments, function(err, res, body) { 63 | if(err) { 64 | return callback(err); 65 | } 66 | var responseBody = body === '' ? JSON.stringify({}) : body; 67 | if(res.statusCode != 200) { 68 | var errData = body; 69 | try { 70 | errData = JSON.parse(body); 71 | } catch (err) { 72 | return callback(err.message || err); 73 | } 74 | return callback(errData, res); 75 | } 76 | return callback(null, res, JSON.parse(responseBody)); 77 | }).auth(this.user, this.password, true); 78 | } 79 | else { 80 | return new Promise(function (resolve, reject) { 81 | return request[method](requestArguments, function(err, res, body) { 82 | if(err) { 83 | return reject(err); 84 | } 85 | var responseBody = body === '' ? JSON.stringify({}) : body; 86 | if(res.statusCode != 200) { 87 | var errData = body; 88 | try { 89 | errData = JSON.parse(body); 90 | } catch (err) { 91 | return reject({ message: err.message || err }); 92 | } 93 | return reject({ message: errData, response: res }); 94 | } 95 | return resolve({ response: res, body: JSON.parse(responseBody) }); 96 | }).auth(this.user, this.password, true); 97 | }.bind(this)); 98 | } 99 | }; 100 | 101 | 102 | 103 | // ----- Cases ----- 104 | 105 | TestRail.prototype.getCase = function (id, callback) { 106 | return this.apiGet('get_case/' + id, callback); 107 | }; 108 | 109 | TestRail.prototype.getCases = function (project_id, filters, callback) { 110 | var uri = 'get_cases/' + project_id; 111 | 112 | if(typeof filters == 'function') { 113 | callback = filters; 114 | return this.apiGet(uri, callback); 115 | } 116 | else { 117 | return this.apiGet(uri, filters, callback); 118 | } 119 | }; 120 | 121 | TestRail.prototype.addCase = function (section_id, data, callback) { 122 | return this.apiPost('add_case/' + section_id, JSON.stringify(data), callback); 123 | }; 124 | 125 | TestRail.prototype.updateCase = function (case_id, data, callback) { 126 | return this.apiPost('update_case/' + case_id, JSON.stringify(data), callback); 127 | }; 128 | 129 | TestRail.prototype.deleteCase = function (case_id, callback) { 130 | return this.apiPost('delete_case/' + case_id, callback); 131 | }; 132 | 133 | // ----- Case Fields ----- 134 | 135 | TestRail.prototype.getCaseFields = function (callback) { 136 | return this.apiGet('get_case_fields', callback); 137 | }; 138 | 139 | // ----- Case Types ----- 140 | 141 | TestRail.prototype.getCaseTypes = function (callback) { 142 | return this.apiGet('get_case_types', callback); 143 | }; 144 | 145 | // ----- Configurations ----- 146 | 147 | TestRail.prototype.getConfigs = function (project_id, callback) { 148 | return this.apiGet('get_configs/' + project_id, callback); 149 | }; 150 | 151 | TestRail.prototype.addConfigGroup = function (project_id, data, callback) { 152 | return this.apiPost('add_config_group/' + project_id, JSON.stringify(data), callback); 153 | }; 154 | 155 | TestRail.prototype.addConfig = function (config_group_id, data, callback) { 156 | return this.apiPost('add_config/' + config_group_id, JSON.stringify(data), callback); 157 | }; 158 | 159 | TestRail.prototype.updateConfigGroup = function (config_group_id, data, callback) { 160 | return this.apiPost('update_config_group/' + config_group_id, JSON.stringify(data), callback); 161 | }; 162 | 163 | TestRail.prototype.updateConfig = function (config_id, data, callback) { 164 | return this.apiPost('update_config/' + config_id, JSON.stringify(data), callback); 165 | }; 166 | 167 | TestRail.prototype.deleteConfigGroup = function (config_group_id, callback) { 168 | return this.apiPost('delete_config_group/' + config_group_id, callback); 169 | }; 170 | 171 | TestRail.prototype.deleteConfig = function (config_id, callback) { 172 | return this.apiPost('delete_config/' + config_id, callback); 173 | }; 174 | 175 | // ----- Milestones ----- 176 | 177 | TestRail.prototype.getMilestone = function (id, callback) { 178 | return this.apiGet('get_milestone/' + id, callback); 179 | }; 180 | 181 | TestRail.prototype.getMilestones = function (project_id, filters, callback) { 182 | var uri = 'get_milestones/' + project_id; 183 | 184 | if(typeof filters == 'function') { 185 | callback = filters; 186 | return this.apiGet(uri, callback); 187 | } 188 | else { 189 | return this.apiGet(uri, filters, callback); 190 | } 191 | }; 192 | 193 | TestRail.prototype.addMilestone = function (project_id, data, callback) { 194 | return this.apiPost('add_milestone/' + project_id, JSON.stringify(data), callback); 195 | }; 196 | 197 | TestRail.prototype.updateMilestone = function (milestone_id, data, callback) { 198 | return this.apiPost('update_milestone/' + milestone_id, JSON.stringify(data), callback); 199 | }; 200 | 201 | TestRail.prototype.deleteMilestone = function (milestone_id, callback) { 202 | return this.apiPost('delete_milestone/' + milestone_id, callback); 203 | }; 204 | 205 | // ----- Plans ----- 206 | 207 | TestRail.prototype.getPlan = function (id, callback) { 208 | return this.apiGet('get_plan/' + id, callback); 209 | }; 210 | 211 | TestRail.prototype.getPlans = function (project_id, filters, callback) { 212 | var uri = 'get_plans/' + project_id; 213 | 214 | if(typeof filters == 'function') { 215 | callback = filters; 216 | return this.apiGet(uri, callback); 217 | } 218 | else { 219 | return this.apiGet(uri, filters, callback); 220 | } 221 | }; 222 | 223 | TestRail.prototype.addPlan = function (project_id, data, callback) { 224 | return this.apiPost('add_plan/' + project_id, JSON.stringify(data), callback); 225 | }; 226 | 227 | TestRail.prototype.addPlanEntry = function (plan_id, data, callback) { 228 | return this.apiPost('add_plan_entry/' + plan_id, JSON.stringify(data), callback); 229 | }; 230 | 231 | TestRail.prototype.updatePlan = function (plan_id, data, callback) { 232 | return this.apiPost('update_plan/' + plan_id, JSON.stringify(data), callback); 233 | }; 234 | 235 | TestRail.prototype.updatePlanEntry = function (plan_id, entry_id, data, callback) { 236 | return this.apiPost('update_plan_entry/' + plan_id + '/' + entry_id, JSON.stringify(data), callback); 237 | }; 238 | 239 | TestRail.prototype.closePlan = function (plan_id, callback) { 240 | return this.apiPost('close_plan/' + plan_id, callback); 241 | }; 242 | 243 | TestRail.prototype.deletePlan = function (plan_id, callback) { 244 | return this.apiPost('delete_plan/' + plan_id, callback); 245 | }; 246 | 247 | TestRail.prototype.deletePlanEntry = function (plan_id, entry_id, callback) { 248 | return this.apiPost('delete_plan_entry/' + plan_id + '/' + entry_id, callback); 249 | }; 250 | 251 | // ----- Priorities ----- 252 | 253 | TestRail.prototype.getPriorities = function (callback) { 254 | return this.apiGet('get_priorities', callback); 255 | }; 256 | 257 | // ----- Projects ----- 258 | 259 | TestRail.prototype.getProject = function (id, callback) { 260 | return this.apiGet('get_project/' + id, callback); 261 | }; 262 | 263 | TestRail.prototype.getProjects = function (filters, callback) { 264 | var uri = 'get_projects'; 265 | 266 | if(typeof filters == 'function') { 267 | callback = filters; 268 | return this.apiGet(uri, callback); 269 | } 270 | else { 271 | return this.apiGet(uri, filters, callback); 272 | } 273 | }; 274 | 275 | TestRail.prototype.addProject = function (data, callback) { 276 | return this.apiPost('add_project', JSON.stringify(data), callback); 277 | }; 278 | 279 | TestRail.prototype.updateProject = function (project_id, data, callback) { 280 | return this.apiPost('update_project/' + project_id, JSON.stringify(data), callback); 281 | }; 282 | 283 | TestRail.prototype.deleteProject = function (project_id, callback) { 284 | return this.apiPost('delete_project/' + project_id, callback); 285 | }; 286 | 287 | // ----- Results ----- 288 | 289 | TestRail.prototype.getResults = function (test_id, filters, callback) { 290 | var uri = 'get_results/' + test_id; 291 | 292 | if(typeof filters == 'function') { 293 | callback = filters; 294 | return this.apiGet(uri, callback); 295 | } 296 | else { 297 | return this.apiGet(uri, filters, callback); 298 | } 299 | }; 300 | 301 | TestRail.prototype.getResultsForCase = function (run_id, case_id, filters, callback) { 302 | var uri = 'get_results_for_case/' + run_id + '/' + case_id; 303 | 304 | if(typeof filters == 'function') { 305 | callback = filters; 306 | return this.apiGet(uri, callback); 307 | } 308 | else { 309 | return this.apiGet(uri, filters, callback); 310 | } 311 | }; 312 | 313 | TestRail.prototype.getResultsForRun = function (run_id, filters, callback) { 314 | var uri = 'get_results_for_run/' + run_id; 315 | 316 | if(typeof filters == 'function') { 317 | callback = filters; 318 | return this.apiGet(uri, callback); 319 | } 320 | else { 321 | return this.apiGet(uri, filters, callback); 322 | } 323 | }; 324 | 325 | TestRail.prototype.addResult = function (test_id, data, callback) { 326 | return this.apiPost('add_result/' + test_id, JSON.stringify(data), callback); 327 | }; 328 | 329 | TestRail.prototype.addResultForCase = function (run_id, case_id, data, callback) { 330 | return this.apiPost('add_result_for_case/' + run_id + '/' + case_id, JSON.stringify(data), callback); 331 | }; 332 | 333 | TestRail.prototype.addResults = function (run_id, data, callback) { 334 | return this.apiPost('add_results/' + run_id, JSON.stringify({ results: data }), callback); 335 | }; 336 | 337 | TestRail.prototype.addResultsForCases = function (run_id, data, callback) { 338 | return this.apiPost('add_results_for_cases/' + run_id, JSON.stringify({ results: data }), callback); 339 | }; 340 | 341 | // ----- Result Fields ----- 342 | 343 | TestRail.prototype.getResultFields = function (callback) { 344 | return this.apiGet('get_result_fields', callback); 345 | }; 346 | 347 | // ----- Runs ----- 348 | 349 | TestRail.prototype.getRun = function (id, callback) { 350 | return this.apiGet('get_run/' + id, callback); 351 | }; 352 | 353 | TestRail.prototype.getRuns = function (project_id, filters, callback) { 354 | var uri = 'get_runs/' + project_id; 355 | 356 | if(typeof filters == 'function') { 357 | callback = filters; 358 | return this.apiGet(uri, callback); 359 | } 360 | else { 361 | return this.apiGet(uri, filters, callback); 362 | } 363 | }; 364 | 365 | TestRail.prototype.addRun = function (project_id, data, callback) { 366 | return this.apiPost('add_run/' + project_id, JSON.stringify(data), callback); 367 | }; 368 | 369 | TestRail.prototype.updateRun = function (run_id, data, callback) { 370 | return this.apiPost('update_run/' + run_id, JSON.stringify(data), callback); 371 | }; 372 | 373 | TestRail.prototype.closeRun = function (run_id, callback) { 374 | return this.apiPost('close_run/' + run_id, callback); 375 | }; 376 | 377 | TestRail.prototype.deleteRun = function (run_id, callback) { 378 | return this.apiPost('delete_run/' + run_id, callback); 379 | }; 380 | 381 | // ----- Sections ----- 382 | 383 | TestRail.prototype.getSection = function (id, callback) { 384 | return this.apiGet('get_section/' + id, callback); 385 | }; 386 | 387 | TestRail.prototype.getSections = function (project_id, filters, callback) { 388 | var uri = 'get_sections/' + project_id; 389 | 390 | if(typeof filters == 'function') { 391 | callback = filters; 392 | return this.apiGet(uri, callback); 393 | } 394 | else { 395 | return this.apiGet(uri, filters, callback); 396 | } 397 | }; 398 | 399 | TestRail.prototype.addSection = function (project_id, data, callback) { 400 | return this.apiPost('add_section/' + project_id, JSON.stringify(data), callback); 401 | }; 402 | 403 | TestRail.prototype.updateSection = function (section_id, data, callback) { 404 | return this.apiPost('update_section/' + section_id, JSON.stringify(data), callback); 405 | }; 406 | 407 | TestRail.prototype.deleteSection = function (section_id, callback) { 408 | return this.apiPost('delete_section/' + section_id, callback); 409 | }; 410 | 411 | // ----- Statuses ----- 412 | 413 | TestRail.prototype.getStatuses = function (callback) { 414 | return this.apiGet('get_statuses', callback); 415 | }; 416 | 417 | // ----- Suites ----- 418 | 419 | TestRail.prototype.getSuite = function (id, callback) { 420 | return this.apiGet('get_suite/' + id, callback); 421 | }; 422 | 423 | TestRail.prototype.getSuites = function (project_id, callback) { 424 | return this.apiGet('get_suites/' + project_id, callback); 425 | }; 426 | 427 | TestRail.prototype.addSuite = function (project_id, data, callback) { 428 | return this.apiPost('add_suite/' + project_id, JSON.stringify(data), callback); 429 | }; 430 | 431 | TestRail.prototype.updateSuite = function (suite_id, data, callback) { 432 | return this.apiPost('update_suite/' + suite_id, JSON.stringify(data), callback); 433 | }; 434 | 435 | TestRail.prototype.deleteSuite = function (suite_id, callback) { 436 | return this.apiPost('delete_suite/' + suite_id, callback); 437 | }; 438 | 439 | // ----- Templates ----- 440 | 441 | TestRail.prototype.getTemplates = function (project_id, callback) { 442 | return this.apiGet('get_templates/' + project_id, callback); 443 | }; 444 | 445 | // ----- Tests ----- 446 | 447 | TestRail.prototype.getTest = function (id, callback) { 448 | return this.apiGet('get_test/' + id, callback); 449 | }; 450 | 451 | TestRail.prototype.getTests = function (run_id, filters, callback) { 452 | var uri = 'get_tests/' + run_id; 453 | 454 | if(typeof filters == 'function') { 455 | callback = filters; 456 | return this.apiGet(uri, callback); 457 | } 458 | else { 459 | return this.apiGet(uri, filters, callback); 460 | } 461 | }; 462 | 463 | // ----- Users ----- 464 | 465 | TestRail.prototype.getUser = function (id, callback) { 466 | return this.apiGet('get_user/' + id, callback); 467 | }; 468 | 469 | TestRail.prototype.getUserByEmail = function (email, callback) { 470 | return this.apiGet('get_user_by_email', {email: email}, callback); 471 | }; 472 | 473 | TestRail.prototype.getUsers = function (callback) { 474 | return this.apiGet('get_users', callback); 475 | }; 476 | 477 | // ---------- 478 | 479 | 480 | module.exports = TestRail; 481 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "testrail-api", 3 | "version": "1.3.6", 4 | "description": "A complete API wrapper for TestRail - with 100% code coverage", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "./node_modules/.bin/_mocha", 8 | "lint": "./node_modules/.bin/eslint index.js", 9 | "cover": "./node_modules/.bin/istanbul cover --report html node_modules/.bin/_mocha --check-leaks", 10 | "travis": "./node_modules/istanbul/lib/cli.js cover ./node_modules/.bin/_mocha", 11 | "coveralls": "cat ./coverage/lcov.info | ./node_modules/.bin/coveralls" 12 | }, 13 | "keywords": [ 14 | "testrail" 15 | ], 16 | "repository": { 17 | "type": "git", 18 | "url": "git://github.com/rundef/node-testrail-api.git" 19 | }, 20 | "author": "Mickael Burguet ", 21 | "license": "MIT", 22 | "engines": { 23 | "node": ">= 0.12.0" 24 | }, 25 | "devDependencies": { 26 | "chai": "^3.5.0", 27 | "coveralls": "^2.11.9", 28 | "eslint": "^2.12.0", 29 | "istanbul": "^0.4.3", 30 | "mocha": "^2.5.3", 31 | "nock": "^8.0.0" 32 | }, 33 | "dependencies": { 34 | "bluebird": "^3.4.6", 35 | "request": "^2.72.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /test/case_fields.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('case_fields api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | 14 | nock('https://rundef.testrail.com') 15 | .get(testrail.uri + 'get_case_fields') 16 | .reply(200, [ 17 | { 18 | 'configs': [ 19 | { 20 | 'context': { 21 | 'is_global': true, 22 | 'project_ids': null 23 | }, 24 | 'id': '..', 25 | 'options': { 26 | 'default_value': '', 27 | 'format': 'markdown', 28 | 'is_required': false, 29 | 'rows': '5' 30 | } 31 | } 32 | ], 33 | 'description': 'The preconditions of this test case. ..', 34 | 'display_order': 1, 35 | 'id': 1, 36 | 'label': 'Preconditions', 37 | 'name': 'preconds', 38 | 'system_name': 'custom_preconds', 39 | 'type_id': 3 40 | } 41 | ]); 42 | 43 | 44 | it('Get all', function (done) { 45 | testrail.getCaseFields(function (err, response, body) { 46 | expect(err).to.be.null; 47 | expect(response).to.be.an.object; 48 | expect(body).to.be.an.array; 49 | done(); 50 | }); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /test/case_types.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('case_types api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | 14 | nock('https://rundef.testrail.com') 15 | .get(testrail.uri + 'get_case_types') 16 | .reply(200, [ 17 | { 18 | 'id': 1, 19 | 'is_default': false, 20 | 'name': 'Automated' 21 | }, 22 | { 23 | 'id': 2, 24 | 'is_default': false, 25 | 'name': 'Functionality' 26 | }, 27 | { 28 | 'id': 6, 29 | 'is_default': true, 30 | 'name': 'Other' 31 | } 32 | ]); 33 | 34 | 35 | it('Get all', function (done) { 36 | testrail.getCaseTypes(function (err, response, body) { 37 | expect(err).to.be.null; 38 | expect(response).to.be.an.object; 39 | expect(body).to.be.an.array; 40 | done(); 41 | }); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /test/cases.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('cases api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | nock('https://rundef.testrail.com') 14 | .get(testrail.uri + 'get_case/1') 15 | .reply(200, { 16 | 'created_by': 5, 17 | 'created_on': 1392300984, 18 | 'custom_expected': '..', 19 | 'custom_preconds': '..', 20 | 'custom_steps': '..', 21 | 'custom_steps_separated': [ 22 | { 23 | 'content': 'Step 1', 24 | 'expected': 'Expected Result 1' 25 | }, 26 | { 27 | 'content': 'Step 2', 28 | 'expected': 'Expected Result 2' 29 | } 30 | ], 31 | 'estimate': '1m 5s', 32 | 'estimate_forecast': null, 33 | 'id': 1, 34 | 'milestone_id': 7, 35 | 'priority_id': 2, 36 | 'refs': 'RF-1, RF-2', 37 | 'section_id': 1, 38 | 'suite_id': 1, 39 | 'title': 'Change document attributes (author, title, organization)', 40 | 'type_id': 4, 41 | 'updated_by': 1, 42 | 'updated_on': 1393586511 43 | }); 44 | 45 | nock('https://rundef.testrail.com') 46 | .get(testrail.uri + 'get_cases/1') 47 | .reply(200, [ 48 | { 'id': 1, 'title': '..' } 49 | ]); 50 | 51 | nock('https://rundef.testrail.com') 52 | .get(testrail.uri + 'get_cases/1&suite_id=2§ion_id=3&updated_by=' + encodeURIComponent('4,5,6')) 53 | .reply(200, [ 54 | { 'id': 1, 'title': '..' } 55 | ]); 56 | 57 | nock('https://rundef.testrail.com') 58 | .post(testrail.uri + 'add_case/1') 59 | .reply(200, { 60 | 'name': 'Release 2.0', 61 | 'due_on': 1394596385 62 | }); 63 | 64 | nock('https://rundef.testrail.com') 65 | .post(testrail.uri + 'update_case/1') 66 | .reply(200, { 67 | 'is_completed': true 68 | }); 69 | 70 | nock('https://rundef.testrail.com') 71 | .post(testrail.uri + 'delete_case/1') 72 | .reply(200, { 73 | 'success': true 74 | }); 75 | 76 | 77 | it('Get one', function (done) { 78 | testrail.getCase(1, function (err, response, body) { 79 | expect(err).to.be.null; 80 | expect(response).to.be.an.object; 81 | expect(body).to.be.an.object; 82 | done(); 83 | }); 84 | }); 85 | 86 | 87 | it('Get all', function (done) { 88 | testrail.getCases(1, function (err, response, body) { 89 | expect(err).to.be.null; 90 | expect(response).to.be.an.object; 91 | expect(body).to.be.an.array; 92 | done(); 93 | }); 94 | }); 95 | 96 | 97 | it('Get all - filtered', function (done) { 98 | testrail.getCases(1, { suite_id: 2, section_id: 3, updated_by: '4,5,6'}, function (err, response, body) { 99 | expect(err).to.be.null; 100 | expect(response).to.be.an.object; 101 | expect(body).to.be.an.array; 102 | done(); 103 | }); 104 | }); 105 | 106 | 107 | it('Add', function (done) { 108 | testrail.addCase(1, { 'custom_preconds': 'These are the preconditions for a test case' }, function (err, response, body) { 109 | expect(err).to.be.null; 110 | expect(response).to.be.an.object; 111 | expect(body).to.be.an.object; 112 | done(); 113 | }); 114 | }); 115 | 116 | 117 | it('Update', function (done) { 118 | testrail.updateCase(1, { 'custom_preconds': 'These are the preconditions for a test case' }, function (err, response, body) { 119 | expect(err).to.be.null; 120 | expect(response).to.be.an.object; 121 | expect(body).to.be.an.object; 122 | done(); 123 | }); 124 | }); 125 | 126 | 127 | it('Delete', function (done) { 128 | testrail.deleteCase(1, function (err, response, body) { 129 | expect(err).to.be.null; 130 | expect(response).to.be.an.object; 131 | expect(body).to.be.an.object; 132 | done(); 133 | }); 134 | }); 135 | }); 136 | -------------------------------------------------------------------------------- /test/configs.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('configs api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | nock('https://rundef.testrail.com') 14 | .get(testrail.uri + 'get_configs/1') 15 | .reply(200, [ 16 | { 17 | 'configs': [ 18 | { 19 | 'group_id': 1, 20 | 'id': 1, 21 | 'name': 'Chrome' 22 | }, 23 | { 24 | 'group_id': 1, 25 | 'id': 2, 26 | 'name': 'Firefox' 27 | }, 28 | { 29 | 'group_id': 1, 30 | 'id': 3, 31 | 'name': 'Internet Explorer' 32 | } 33 | ], 34 | 'id': 1, 35 | 'name': 'Browsers', 36 | 'project_id': 1 37 | } 38 | ]); 39 | 40 | nock('https://rundef.testrail.com') 41 | .post(testrail.uri + 'add_config_group/1') 42 | .reply(200, { 43 | 'success': true 44 | }); 45 | 46 | nock('https://rundef.testrail.com') 47 | .post(testrail.uri + 'add_config/1') 48 | .reply(200, { 49 | 'success': true 50 | }); 51 | 52 | nock('https://rundef.testrail.com') 53 | .post(testrail.uri + 'update_config_group/1') 54 | .reply(200, { 55 | 'success': true 56 | }); 57 | 58 | nock('https://rundef.testrail.com') 59 | .post(testrail.uri + 'update_config/1') 60 | .reply(200, { 61 | 'success': true 62 | }); 63 | 64 | nock('https://rundef.testrail.com') 65 | .post(testrail.uri + 'delete_config_group/1') 66 | .reply(200, { 67 | 'success': true 68 | }); 69 | 70 | nock('https://rundef.testrail.com') 71 | .post(testrail.uri + 'delete_config/1') 72 | .reply(200, { 73 | 'success': true 74 | }); 75 | 76 | 77 | 78 | 79 | it('Get all', function (done) { 80 | testrail.getConfigs(1, function (err, response, body) { 81 | expect(err).to.be.null; 82 | expect(response).to.be.an.object; 83 | expect(body).to.be.an.array; 84 | done(); 85 | }); 86 | }); 87 | 88 | 89 | it('Add config group', function (done) { 90 | testrail.addConfigGroup(1, { 'name': 'Browsers' }, function (err, response, body) { 91 | expect(err).to.be.null; 92 | expect(response).to.be.an.object; 93 | expect(body).to.be.an.object; 94 | done(); 95 | }); 96 | }); 97 | 98 | 99 | it('Add config', function (done) { 100 | testrail.addConfig(1, { 'name': 'Chrome' }, function (err, response, body) { 101 | expect(err).to.be.null; 102 | expect(response).to.be.an.object; 103 | expect(body).to.be.an.object; 104 | done(); 105 | }); 106 | }); 107 | 108 | 109 | it('Update config group', function (done) { 110 | testrail.updateConfigGroup(1, { 'name': 'Browsers' }, function (err, response, body) { 111 | expect(err).to.be.null; 112 | expect(response).to.be.an.object; 113 | expect(body).to.be.an.object; 114 | done(); 115 | }); 116 | }); 117 | 118 | 119 | it('Update config', function (done) { 120 | testrail.updateConfig(1, { 'name': 'Chrome' }, function (err, response, body) { 121 | expect(err).to.be.null; 122 | expect(response).to.be.an.object; 123 | expect(body).to.be.an.object; 124 | done(); 125 | }); 126 | }); 127 | 128 | it('Delete config group', function (done) { 129 | testrail.deleteConfigGroup(1, function (err, response, body) { 130 | expect(err).to.be.null; 131 | expect(response).to.be.an.object; 132 | expect(body).to.be.an.object; 133 | done(); 134 | }); 135 | }); 136 | 137 | it('Delete config', function (done) { 138 | testrail.deleteConfig(1, function (err, response, body) { 139 | expect(err).to.be.null; 140 | expect(response).to.be.an.object; 141 | expect(body).to.be.an.object; 142 | done(); 143 | }); 144 | }); 145 | }); 146 | -------------------------------------------------------------------------------- /test/milestones.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('milestones api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | nock('https://rundef.testrail.com') 14 | .get(testrail.uri + 'get_milestone/1') 15 | .reply(200, { 16 | 'completed_on': 1389968184, 17 | 'description': '...', 18 | 'due_on': 1391968184, 19 | 'id': 1, 20 | 'is_completed': true, 21 | 'name': 'Release 1.5', 22 | 'project_id': 1, 23 | 'url': 'http:///testrail/index.php?/milestones/view/1' 24 | }); 25 | 26 | nock('https://rundef.testrail.com') 27 | .get(testrail.uri + 'get_milestones/1') 28 | .reply(200, [ 29 | { 'id': 1, 'name': 'Release 1.5' } 30 | ]); 31 | 32 | nock('https://rundef.testrail.com') 33 | .get(testrail.uri + 'get_milestones/1&is_completed=0') 34 | .reply(200, [ 35 | { 'id': 1, 'name': 'Release 1.5' } 36 | ]); 37 | 38 | nock('https://rundef.testrail.com') 39 | .post(testrail.uri + 'add_milestone/1') 40 | .reply(200, { 41 | 'name': 'Release 2.0', 42 | 'due_on': 1394596385 43 | }); 44 | 45 | nock('https://rundef.testrail.com') 46 | .post(testrail.uri + 'update_milestone/1') 47 | .reply(200, { 48 | 'is_completed': true 49 | }); 50 | 51 | nock('https://rundef.testrail.com') 52 | .post(testrail.uri + 'delete_milestone/1') 53 | .reply(200, { 54 | 'success': true 55 | }); 56 | 57 | 58 | it('Get one', function (done) { 59 | testrail.getMilestone(1, function (err, response, body) { 60 | expect(err).to.be.null; 61 | expect(response).to.be.an.object; 62 | expect(body).to.be.an.object; 63 | done(); 64 | }); 65 | }); 66 | 67 | 68 | it('Get all', function (done) { 69 | testrail.getMilestones(1, function (err, response, body) { 70 | expect(err).to.be.null; 71 | expect(response).to.be.an.object; 72 | expect(body).to.be.an.array; 73 | done(); 74 | }); 75 | }); 76 | 77 | 78 | it('Get all - filtered', function (done) { 79 | testrail.getMilestones(1, { is_completed: 0 }, function (err, response, body) { 80 | expect(err).to.be.null; 81 | expect(response).to.be.an.object; 82 | expect(body).to.be.an.array; 83 | done(); 84 | }); 85 | }); 86 | 87 | 88 | it('Add', function (done) { 89 | testrail.addMilestone(1, { 'name': 'Release 2.0', 'due_on': 1394596385 }, function (err, response, body) { 90 | expect(err).to.be.null; 91 | expect(response).to.be.an.object; 92 | expect(body).to.be.an.object; 93 | done(); 94 | }); 95 | }); 96 | 97 | 98 | it('Update', function (done) { 99 | testrail.updateMilestone(1, { 'is_completed': 1 }, function (err, response, body) { 100 | expect(err).to.be.null; 101 | expect(response).to.be.an.object; 102 | expect(body).to.be.an.object; 103 | done(); 104 | }); 105 | }); 106 | 107 | 108 | it('Delete', function (done) { 109 | testrail.deleteMilestone(1, function (err, response, body) { 110 | expect(err).to.be.null; 111 | expect(response).to.be.an.object; 112 | expect(body).to.be.an.object; 113 | done(); 114 | }); 115 | }); 116 | }); 117 | -------------------------------------------------------------------------------- /test/plans.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('plans api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | nock('https://rundef.testrail.com') 14 | .get(testrail.uri + 'get_plan/1') 15 | .reply(200, { 16 | 'assignedto_id': null, 17 | 'blocked_count': 2, 18 | 'completed_on': null 19 | }); 20 | 21 | nock('https://rundef.testrail.com') 22 | .get(testrail.uri + 'get_plans/1') 23 | .reply(200, [ 24 | { 'id': 1, 'title': '..' } 25 | ]); 26 | 27 | nock('https://rundef.testrail.com') 28 | .get(testrail.uri + 'get_plans/1&is_completed=0') 29 | .reply(200, [ 30 | { 'id': 1, 'title': '..' } 31 | ]); 32 | 33 | nock('https://rundef.testrail.com') 34 | .post(testrail.uri + 'add_plan/1') 35 | .reply(200, { 36 | 'success': true 37 | }); 38 | 39 | nock('https://rundef.testrail.com') 40 | .post(testrail.uri + 'add_plan_entry/1') 41 | .reply(200, { 42 | 'success': true 43 | }); 44 | 45 | nock('https://rundef.testrail.com') 46 | .post(testrail.uri + 'update_plan/1') 47 | .reply(200, { 48 | 'success': true 49 | }); 50 | 51 | nock('https://rundef.testrail.com') 52 | .post(testrail.uri + 'update_plan_entry/1/2') 53 | .reply(200, { 54 | 'success': true 55 | }); 56 | 57 | nock('https://rundef.testrail.com') 58 | .post(testrail.uri + 'close_plan/1') 59 | .reply(200, { 60 | 'success': true 61 | }); 62 | 63 | nock('https://rundef.testrail.com') 64 | .post(testrail.uri + 'delete_plan/1') 65 | .reply(200, { 66 | 'success': true 67 | }); 68 | 69 | nock('https://rundef.testrail.com') 70 | .post(testrail.uri + 'delete_plan_entry/1/2') 71 | .reply(200, { 72 | 'success': true 73 | }); 74 | 75 | 76 | 77 | it('Get one', function (done) { 78 | testrail.getPlan(1, function (err, response, body) { 79 | expect(err).to.be.null; 80 | expect(response).to.be.an.object; 81 | expect(body).to.be.an.object; 82 | done(); 83 | }); 84 | }); 85 | 86 | 87 | it('Get all', function (done) { 88 | testrail.getPlans(1, function (err, response, body) { 89 | expect(err).to.be.null; 90 | expect(response).to.be.an.object; 91 | expect(body).to.be.an.array; 92 | done(); 93 | }); 94 | }); 95 | 96 | 97 | it('Get all - filtered', function (done) { 98 | testrail.getPlans(1, { is_completed: 0 }, function (err, response, body) { 99 | expect(err).to.be.null; 100 | expect(response).to.be.an.object; 101 | expect(body).to.be.an.array; 102 | done(); 103 | }); 104 | }); 105 | 106 | 107 | it('Add plan entry', function (done) { 108 | testrail.addPlanEntry(1, { 'name': 'Browsers' }, function (err, response, body) { 109 | expect(err).to.be.null; 110 | expect(response).to.be.an.object; 111 | expect(body).to.be.an.object; 112 | done(); 113 | }); 114 | }); 115 | 116 | 117 | it('Add plan', function (done) { 118 | testrail.addPlan(1, { 'name': 'Chrome' }, function (err, response, body) { 119 | expect(err).to.be.null; 120 | expect(response).to.be.an.object; 121 | expect(body).to.be.an.object; 122 | done(); 123 | }); 124 | }); 125 | 126 | 127 | it('Update plan entry', function (done) { 128 | testrail.updatePlanEntry(1, 2, { 'name': 'Browsers' }, function (err, response, body) { 129 | expect(err).to.be.null; 130 | expect(response).to.be.an.object; 131 | expect(body).to.be.an.object; 132 | done(); 133 | }); 134 | }); 135 | 136 | 137 | it('Update plan', function (done) { 138 | testrail.updatePlan(1, { 'name': 'Chrome' }, function (err, response, body) { 139 | expect(err).to.be.null; 140 | expect(response).to.be.an.object; 141 | expect(body).to.be.an.object; 142 | done(); 143 | }); 144 | }); 145 | 146 | it('Close plan', function (done) { 147 | testrail.closePlan(1, function (err, response, body) { 148 | expect(err).to.be.null; 149 | expect(response).to.be.an.object; 150 | expect(body).to.be.an.object; 151 | done(); 152 | }); 153 | }); 154 | 155 | it('Delete plan entry', function (done) { 156 | testrail.deletePlanEntry(1, 2, function (err, response, body) { 157 | expect(err).to.be.null; 158 | expect(response).to.be.an.object; 159 | expect(body).to.be.an.object; 160 | done(); 161 | }); 162 | }); 163 | 164 | it('Delete plan', function (done) { 165 | testrail.deletePlan(1, function (err, response, body) { 166 | expect(err).to.be.null; 167 | expect(response).to.be.an.object; 168 | expect(body).to.be.an.object; 169 | done(); 170 | }); 171 | }); 172 | }); 173 | -------------------------------------------------------------------------------- /test/priorities.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('priorities api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | 14 | nock('https://rundef.testrail.com') 15 | .get(testrail.uri + 'get_priorities') 16 | .reply(200, [ 17 | { 18 | 'id': 1, 19 | 'is_default': false, 20 | 'name': '1 - Don\'t Test', 21 | 'priority': 1, 22 | 'short_name': '1 - Don\'t' 23 | }, 24 | { 25 | 'id': 4, 26 | 'is_default': true, 27 | 'name': '4 - Must Test', 28 | 'priority': 4, 29 | 'short_name': '4 - Must' 30 | } 31 | ]); 32 | 33 | 34 | it('Get all', function (done) { 35 | testrail.getPriorities(function (err, response, body) { 36 | expect(err).to.be.null; 37 | expect(response).to.be.an.object; 38 | expect(body).to.be.an.array; 39 | done(); 40 | }); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /test/projects.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('projects api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | nock('https://rundef.testrail.com') 14 | .get(testrail.uri + 'get_project/1') 15 | .reply(200, { 16 | 'announcement': '..', 17 | 'completed_on': null, 18 | 'id': 1, 19 | 'is_completed': false, 20 | 'name': 'Datahub', 21 | 'show_announcement': true, 22 | 'url': 'http:///testrail/index.php?/projects/overview/1' 23 | }); 24 | 25 | nock('https://rundef.testrail.com') 26 | .get(testrail.uri + 'get_projects') 27 | .reply(200, [ 28 | { 'id': 1, 'title': '..' } 29 | ]); 30 | 31 | nock('https://rundef.testrail.com') 32 | .get(testrail.uri + 'get_projects&is_completed=0') 33 | .reply(200, [ 34 | { 'id': 1, 'title': '..' } 35 | ]); 36 | 37 | nock('https://rundef.testrail.com') 38 | .post(testrail.uri + 'add_project') 39 | .reply(200, { 40 | 'announcement': '..', 41 | 'completed_on': null, 42 | 'id': 1, 43 | 'is_completed': false, 44 | 'name': 'Datahub', 45 | 'show_announcement': true, 46 | 'url': 'http:///testrail/index.php?/projects/overview/1' 47 | }); 48 | 49 | nock('https://rundef.testrail.com') 50 | .post(testrail.uri + 'update_project/1') 51 | .reply(200, { 52 | 'is_completed': true 53 | }); 54 | 55 | nock('https://rundef.testrail.com') 56 | .post(testrail.uri + 'delete_project/1') 57 | .reply(200, { 58 | 'success': true 59 | }); 60 | 61 | 62 | it('Get one', function (done) { 63 | testrail.getProject(1, function (err, response, body) { 64 | expect(err).to.be.null; 65 | expect(response).to.be.an.object; 66 | expect(body).to.be.an.object; 67 | done(); 68 | }); 69 | }); 70 | 71 | 72 | it('Get all', function (done) { 73 | testrail.getProjects(function (err, response, body) { 74 | expect(err).to.be.null; 75 | expect(response).to.be.an.object; 76 | expect(body).to.be.an.array; 77 | done(); 78 | }); 79 | }); 80 | 81 | 82 | it('Get all - filtered', function (done) { 83 | testrail.getProjects({ is_completed: '0' }, function (err, response, body) { 84 | expect(err).to.be.null; 85 | expect(response).to.be.an.object; 86 | expect(body).to.be.an.array; 87 | done(); 88 | }); 89 | }); 90 | 91 | 92 | it('Add', function (done) { 93 | testrail.addProject({ 'is_completed': true }, function (err, response, body) { 94 | expect(err).to.be.null; 95 | expect(response).to.be.an.object; 96 | expect(body).to.be.an.object; 97 | done(); 98 | }); 99 | }); 100 | 101 | 102 | it('Update', function (done) { 103 | testrail.updateProject(1, { 'is_completed': true }, function (err, response, body) { 104 | expect(err).to.be.null; 105 | expect(response).to.be.an.object; 106 | expect(body).to.be.an.object; 107 | done(); 108 | }); 109 | }); 110 | 111 | 112 | it('Delete', function (done) { 113 | testrail.deleteProject(1, function (err, response, body) { 114 | expect(err).to.be.null; 115 | expect(response).to.be.an.object; 116 | expect(body).to.be.an.object; 117 | done(); 118 | }); 119 | }); 120 | }); 121 | -------------------------------------------------------------------------------- /test/result_fields.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('result_fields api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | 14 | nock('https://rundef.testrail.com') 15 | .get(testrail.uri + 'get_result_fields') 16 | .reply(200, [ 17 | { 18 | 'configs': [ 19 | { 20 | 'context': { 21 | 'is_global': true, 22 | 'project_ids': null 23 | }, 24 | 'id': '..', 25 | 'options': { 26 | 'format': 'markdown', 27 | 'has_actual': false, 28 | 'has_expected': true, 29 | 'is_required': false 30 | } 31 | } 32 | ], 33 | 'description': null, 34 | 'display_order': 1, 35 | 'id': 5, 36 | 'label': 'Steps', 37 | 'name': 'step_results', 38 | 'system_name': 'custom_step_results', 39 | 'type_id': 11 40 | } 41 | ]); 42 | 43 | 44 | it('Get all', function (done) { 45 | testrail.getResultFields(function (err, response, body) { 46 | expect(err).to.be.null; 47 | expect(response).to.be.an.object; 48 | expect(body).to.be.an.array; 49 | done(); 50 | }); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /test/results.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('plans api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | nock('https://rundef.testrail.com') 14 | .get(testrail.uri + 'get_results/1') 15 | .reply(200, [ 16 | { 'id': 1, 'title': '..' } 17 | ]); 18 | 19 | nock('https://rundef.testrail.com') 20 | .get(testrail.uri + 'get_results/1&status_id=2') 21 | .reply(200, [ 22 | { 'id': 1, 'title': '..' } 23 | ]); 24 | 25 | nock('https://rundef.testrail.com') 26 | .get(testrail.uri + 'get_results_for_case/1/2') 27 | .reply(200, [ 28 | { 'id': 1, 'title': '..' } 29 | ]); 30 | 31 | nock('https://rundef.testrail.com') 32 | .get(testrail.uri + 'get_results_for_case/1/2&status_id=3') 33 | .reply(200, [ 34 | { 'id': 1, 'title': '..' } 35 | ]); 36 | 37 | nock('https://rundef.testrail.com') 38 | .get(testrail.uri + 'get_results_for_run/1') 39 | .reply(200, [ 40 | { 'id': 1, 'title': '..' } 41 | ]); 42 | 43 | nock('https://rundef.testrail.com') 44 | .get(testrail.uri + 'get_results_for_run/1&status_id=2') 45 | .reply(200, [ 46 | { 'id': 1, 'title': '..' } 47 | ]); 48 | 49 | nock('https://rundef.testrail.com') 50 | .post(testrail.uri + 'add_result/1') 51 | .reply(200, { 52 | 'success': true 53 | }); 54 | 55 | nock('https://rundef.testrail.com') 56 | .post(testrail.uri + 'add_result_for_case/1/2') 57 | .reply(200, { 58 | 'success': true 59 | }); 60 | 61 | nock('https://rundef.testrail.com') 62 | .post(testrail.uri + 'add_results/1') 63 | .reply(200, [ 64 | { 'id': 1, 'title': '..' } 65 | ]); 66 | 67 | nock('https://rundef.testrail.com') 68 | .post(testrail.uri + 'add_results_for_cases/1') 69 | .reply(200, [ 70 | { 'id': 1, 'title': '..' } 71 | ]); 72 | 73 | 74 | it('Get all', function (done) { 75 | testrail.getResults(1, function (err, response, body) { 76 | expect(err).to.be.null; 77 | expect(response).to.be.an.object; 78 | expect(body).to.be.an.array; 79 | done(); 80 | }); 81 | }); 82 | 83 | 84 | it('Get all - filtered', function (done) { 85 | testrail.getResults(1, { status_id: 2 }, function (err, response, body) { 86 | expect(err).to.be.null; 87 | expect(response).to.be.an.object; 88 | expect(body).to.be.an.array; 89 | done(); 90 | }); 91 | }); 92 | 93 | 94 | it('Get all for case', function (done) { 95 | testrail.getResultsForCase(1, 2, function (err, response, body) { 96 | expect(err).to.be.null; 97 | expect(response).to.be.an.object; 98 | expect(body).to.be.an.array; 99 | done(); 100 | }); 101 | }); 102 | 103 | 104 | it('Get all for case - filtered', function (done) { 105 | testrail.getResultsForCase(1, 2, { status_id: 3 }, function (err, response, body) { 106 | expect(err).to.be.null; 107 | expect(response).to.be.an.object; 108 | expect(body).to.be.an.array; 109 | done(); 110 | }); 111 | }); 112 | 113 | 114 | it('Get all for run', function (done) { 115 | testrail.getResultsForRun(1, function (err, response, body) { 116 | expect(err).to.be.null; 117 | expect(response).to.be.an.object; 118 | expect(body).to.be.an.array; 119 | done(); 120 | }); 121 | }); 122 | 123 | 124 | it('Get all for run - filtered', function (done) { 125 | testrail.getResultsForRun(1, { status_id: 2 }, function (err, response, body) { 126 | expect(err).to.be.null; 127 | expect(response).to.be.an.object; 128 | expect(body).to.be.an.array; 129 | done(); 130 | }); 131 | }); 132 | 133 | 134 | it('Add one', function (done) { 135 | testrail.addResult(1, { 'comment': 'This test failed' }, function (err, response, body) { 136 | expect(err).to.be.null; 137 | expect(response).to.be.an.object; 138 | expect(body).to.be.an.object; 139 | done(); 140 | }); 141 | }); 142 | 143 | 144 | it('Add one for case', function (done) { 145 | testrail.addResultForCase(1, 2, { 'comment': 'This test failed' }, function (err, response, body) { 146 | expect(err).to.be.null; 147 | expect(response).to.be.an.object; 148 | expect(body).to.be.an.object; 149 | done(); 150 | }); 151 | }); 152 | 153 | 154 | it('Add multiple', function (done) { 155 | testrail.addResults(1, [{ 'comment': 'This test failed' }], function (err, response, body) { 156 | expect(err).to.be.null; 157 | expect(response).to.be.an.object; 158 | expect(body).to.be.an.array; 159 | done(); 160 | }); 161 | }); 162 | 163 | 164 | it('Add multiple for case', function (done) { 165 | testrail.addResultsForCases(1, [{ 'comment': 'This test failed' }], function (err, response, body) { 166 | expect(err).to.be.null; 167 | expect(response).to.be.an.object; 168 | expect(body).to.be.an.array; 169 | done(); 170 | }); 171 | }); 172 | }); 173 | -------------------------------------------------------------------------------- /test/runs.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('runs api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | nock('https://rundef.testrail.com') 14 | .get(testrail.uri + 'get_run/1') 15 | .reply(200, { 16 | 'assignedto_id': 6, 17 | 'blocked_count': 0, 18 | 'completed_on': null, 19 | 'config': 'Firefox, Ubuntu 12' 20 | }); 21 | 22 | nock('https://rundef.testrail.com') 23 | .get(testrail.uri + 'get_runs/1') 24 | .reply(200, [ 25 | { 'id': 1, 'name': 'Test run 1' } 26 | ]); 27 | 28 | nock('https://rundef.testrail.com') 29 | .get(testrail.uri + 'get_runs/1&is_completed=0&suite_id=4') 30 | .reply(200, { 31 | 'assignedto_id': 6, 32 | 'blocked_count': 0, 33 | 'completed_on': null, 34 | 'config': 'Firefox, Ubuntu 12' 35 | }); 36 | 37 | nock('https://rundef.testrail.com') 38 | .post(testrail.uri + 'add_run/1') 39 | .reply(200, { 40 | 'assignedto_id': 6, 41 | 'blocked_count': 0, 42 | 'completed_on': null, 43 | 'config': 'Firefox, Ubuntu 12' 44 | }); 45 | 46 | nock('https://rundef.testrail.com') 47 | .post(testrail.uri + 'update_run/1') 48 | .reply(200, { 49 | 'assignedto_id': 6, 50 | 'blocked_count': 0, 51 | 'completed_on': null, 52 | 'config': 'Firefox, Ubuntu 12' 53 | }); 54 | 55 | nock('https://rundef.testrail.com') 56 | .post(testrail.uri + 'close_run/1') 57 | .reply(200, { 58 | 'assignedto_id': 6, 59 | 'blocked_count': 0, 60 | 'completed_on': null, 61 | 'config': 'Firefox, Ubuntu 12' 62 | }); 63 | 64 | nock('https://rundef.testrail.com') 65 | .post(testrail.uri + 'delete_run/1') 66 | .reply(200, { 67 | 'success': true 68 | }); 69 | 70 | 71 | it('Get one', function (done) { 72 | testrail.getRun(1, function (err, response, body) { 73 | expect(err).to.be.null; 74 | expect(response).to.be.an.object; 75 | expect(body).to.be.an.object; 76 | done(); 77 | }); 78 | }); 79 | 80 | 81 | it('Get all', function (done) { 82 | testrail.getRuns(1, function (err, response, body) { 83 | expect(err).to.be.null; 84 | expect(response).to.be.an.object; 85 | expect(body).to.be.an.array; 86 | done(); 87 | }); 88 | }); 89 | 90 | 91 | it('Get all - filtered', function (done) { 92 | testrail.getRuns(1, { is_completed: 0, suite_id: 4 }, function (err, response, body) { 93 | expect(err).to.be.null; 94 | expect(response).to.be.an.object; 95 | expect(body).to.be.an.array; 96 | done(); 97 | }); 98 | }); 99 | 100 | 101 | it('Add', function (done) { 102 | testrail.addRun(1, { 'suite_id': 5, 'name': 'This is a new test run' }, function (err, response, body) { 103 | expect(err).to.be.null; 104 | expect(response).to.be.an.object; 105 | expect(body).to.be.an.object; 106 | done(); 107 | }); 108 | }); 109 | 110 | 111 | it('Update', function (done) { 112 | testrail.updateRun(1, { 'description': 'A description for the test run' }, function (err, response, body) { 113 | expect(err).to.be.null; 114 | expect(response).to.be.an.object; 115 | expect(body).to.be.an.object; 116 | done(); 117 | }); 118 | }); 119 | 120 | 121 | it('Close', function (done) { 122 | testrail.closeRun(1, function (err, response, body) { 123 | expect(err).to.be.null; 124 | expect(response).to.be.an.object; 125 | expect(body).to.be.an.object; 126 | done(); 127 | }); 128 | }); 129 | 130 | 131 | it('Delete', function (done) { 132 | testrail.deleteRun(1, function (err, response, body) { 133 | expect(err).to.be.null; 134 | expect(response).to.be.an.object; 135 | expect(body).to.be.an.object; 136 | done(); 137 | }); 138 | }); 139 | }); 140 | -------------------------------------------------------------------------------- /test/sections.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('sections api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | nock('https://rundef.testrail.com') 14 | .persist() 15 | .get(testrail.uri + 'get_section/1') 16 | .reply(200, { 17 | 'depth': 0, 18 | 'description': null, 19 | 'display_order': 1, 20 | 'id': 1, 21 | 'name': 'Prerequisites', 22 | 'parent_id': null, 23 | 'suite_id': 1 24 | }); 25 | 26 | 27 | nock('https://rundef.testrail.com') 28 | .persist() 29 | .get(testrail.uri + 'get_sections/1') 30 | .reply(200, [ 31 | { 32 | 'depth': 0, 33 | 'display_order': 1, 34 | 'id': 1, 35 | 'name': 'Prerequisites', 36 | 'parent_id': null, 37 | 'suite_id': 1 38 | }, 39 | { 40 | 'depth': 0, 41 | 'display_order': 2, 42 | 'id': 2, 43 | 'name': 'Documentation & Help', 44 | 'parent_id': null, 45 | 'suite_id': 1 46 | }, 47 | { 48 | 'depth': 1, // A child section 49 | 'display_order': 3, 50 | 'id': 3, 51 | 'name': 'Licensing & Terms', 52 | 'parent_id': 2, // Points to the parent section 53 | 'suite_id': 1 54 | } 55 | ]); 56 | 57 | nock('https://rundef.testrail.com') 58 | .get(testrail.uri + 'get_sections/1&suite_id=2') 59 | .reply(200, [ 60 | { 61 | 'depth': 0, 62 | 'display_order': 1, 63 | 'id': 1, 64 | 'name': 'Prerequisites', 65 | 'parent_id': null, 66 | 'suite_id': 1 67 | } 68 | ]); 69 | 70 | nock('https://rundef.testrail.com') 71 | .post(testrail.uri + 'add_section/1') 72 | .reply(200, { 73 | 'depth': 0, 74 | 'description': null, 75 | 'display_order': 1, 76 | 'id': 1, 77 | 'name': 'Prerequisites', 78 | 'parent_id': null, 79 | 'suite_id': 1 80 | }); 81 | 82 | nock('https://rundef.testrail.com') 83 | .post(testrail.uri + 'update_section/1') 84 | .reply(200, { 85 | 'depth': 0, 86 | 'description': null, 87 | 'display_order': 1, 88 | 'id': 1, 89 | 'name': 'Prerequisites', 90 | 'parent_id': null, 91 | 'suite_id': 1 92 | }); 93 | 94 | nock('https://rundef.testrail.com') 95 | .post(testrail.uri + 'delete_section/1') 96 | .reply(200, { 97 | 'success': true 98 | }); 99 | 100 | 101 | it('Get one', function (done) { 102 | testrail.getSection(1, function (err, response, body) { 103 | expect(err).to.be.null; 104 | expect(response).to.be.an.object; 105 | expect(body).to.be.an.object; 106 | done(); 107 | }); 108 | }); 109 | 110 | it('Get one (Promise)', function (done) { 111 | testrail.getSection(1).then(function (result) { 112 | expect(result).to.be.an.object; 113 | expect(result.body).to.be.an.object; 114 | done(); 115 | }).catch(done); 116 | }); 117 | 118 | it('Get all', function (done) { 119 | testrail.getSections(1, function (err, response, body) { 120 | expect(err).to.be.null; 121 | expect(response).to.be.an.object; 122 | expect(body).to.be.an.array; 123 | done(); 124 | }); 125 | }); 126 | 127 | it('Get all (Promise)', function (done) { 128 | testrail.getSections(1).then(function (result) { 129 | expect(result.body).to.be.an.array; 130 | done(); 131 | }).catch(done); 132 | }); 133 | 134 | 135 | it('Get all - filtered', function (done) { 136 | testrail.getSections(1, { suite_id: 2 }, function (err, response, body) { 137 | expect(err).to.be.null; 138 | expect(response).to.be.an.object; 139 | expect(body).to.be.an.array; 140 | done(); 141 | }); 142 | }); 143 | 144 | 145 | it('Add', function (done) { 146 | testrail.addSection(1, { 'suite_id': 5, 'name': 'This is a new section', 'parent_id': 10 }, function (err, response, body) { 147 | expect(err).to.be.null; 148 | expect(response).to.be.an.object; 149 | expect(body).to.be.an.object; 150 | done(); 151 | }); 152 | }); 153 | 154 | 155 | it('Update', function (done) { 156 | testrail.updateSection(1, { 'suite_id': 5, 'name': 'This is a new section', 'parent_id': 10 }, function (err, response, body) { 157 | expect(err).to.be.null; 158 | expect(response).to.be.an.object; 159 | expect(body).to.be.an.object; 160 | done(); 161 | }); 162 | }); 163 | 164 | 165 | it('Delete', function (done) { 166 | testrail.deleteSection(1, function (err, response, body) { 167 | expect(err).to.be.null; 168 | expect(response).to.be.an.object; 169 | expect(body).to.be.an.object; 170 | done(); 171 | }); 172 | }); 173 | }); 174 | -------------------------------------------------------------------------------- /test/statuses.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('statuses api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | 14 | nock('https://rundef.testrail.com') 15 | .get(testrail.uri + 'get_statuses') 16 | .reply(200, [ 17 | { 18 | 'color_bright': 12709313, 19 | 'color_dark': 6667107, 20 | 'color_medium': 9820525, 21 | 'id': 1, 22 | 'is_final': true, 23 | 'is_system': true, 24 | 'is_untested': false, 25 | 'label': 'Passed', 26 | 'name': 'passed' 27 | }, 28 | { 29 | 'color_bright': 16631751, 30 | 'color_dark': 14250867, 31 | 'color_medium': 15829135, 32 | 'id': 5, 33 | 'is_final': true, 34 | 'is_system': true, 35 | 'is_untested': false, 36 | 'label': 'Failed', 37 | 'name': 'failed' 38 | }, 39 | { 40 | 'color_bright': 13684944, 41 | 'color_dark': 0, 42 | 'color_medium': 10526880, 43 | 'id': 6, 44 | 'is_final': false, 45 | 'is_system': false, 46 | 'is_untested': false, 47 | 'label': 'Custom', 48 | 'name': 'custom_status1' 49 | } 50 | ]); 51 | 52 | 53 | it('Get all', function (done) { 54 | testrail.getStatuses(function (err, response, body) { 55 | expect(err).to.be.null; 56 | expect(response).to.be.an.object; 57 | expect(body).to.be.an.array; 58 | done(); 59 | }); 60 | }); 61 | }); 62 | -------------------------------------------------------------------------------- /test/suites.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('suites api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | nock('https://rundef.testrail.com') 14 | .get(testrail.uri + 'get_suite/1') 15 | .reply(200, { 16 | 'description': '..', 17 | 'id': 1, 18 | 'name': 'Setup & Installation', 19 | 'project_id': 1, 20 | 'url': 'http:///testrail/index.php?/suites/view/1' 21 | }); 22 | 23 | 24 | nock('https://rundef.testrail.com') 25 | .get(testrail.uri + 'get_suites/1') 26 | .reply(200, [ 27 | { 'id': 1, 'name': 'Setup & Installation' }, 28 | { 'id': 2, 'name': 'Document Editing' } 29 | ]); 30 | 31 | nock('https://rundef.testrail.com') 32 | .post(testrail.uri + 'add_suite/1') 33 | .reply(200, { 34 | 'description': '..', 35 | 'id': 1, 36 | 'name': 'Setup & Installation', 37 | 'project_id': 1, 38 | 'url': 'http:///testrail/index.php?/suites/view/1' 39 | }); 40 | 41 | nock('https://rundef.testrail.com') 42 | .post(testrail.uri + 'add_suite/2') 43 | .reply(403, { 44 | error: 'No permissions to add test suites or no access to the project' 45 | }); 46 | 47 | nock('https://rundef.testrail.com') 48 | .post(testrail.uri + 'update_suite/1') 49 | .reply(200, { 50 | 'description': '..', 51 | 'id': 1, 52 | 'name': 'Setup & Installation', 53 | 'project_id': 1, 54 | 'url': 'http:///testrail/index.php?/suites/view/1' 55 | }); 56 | 57 | nock('https://rundef.testrail.com') 58 | .post(testrail.uri + 'delete_suite/1') 59 | .reply(200, { 60 | 'success': true 61 | }); 62 | 63 | 64 | it('Get one', function (done) { 65 | testrail.getSuite(1, function (err, response, body) { 66 | expect(err).to.be.null; 67 | expect(response).to.be.an.object; 68 | expect(body).to.be.an.object; 69 | done(); 70 | }); 71 | }); 72 | 73 | 74 | it('Get all', function (done) { 75 | testrail.getSuites(1, function (err, response, body) { 76 | expect(err).to.be.null; 77 | expect(response).to.be.an.object; 78 | expect(body).to.be.an.array; 79 | done(); 80 | }); 81 | }); 82 | 83 | 84 | it('Add - success', function (done) { 85 | testrail.addSuite(1, { 'name': 'This is a new test suite' }, function (err, response, body) { 86 | expect(err).to.be.null; 87 | expect(response).to.be.an.object; 88 | expect(body).to.be.an.object; 89 | done(); 90 | }); 91 | }); 92 | 93 | 94 | it('Add - error', function (done) { 95 | testrail.addSuite(2, { 'name': 'This is a new test suite' }, function (err, response, body) { 96 | expect(err).to.not.be.null; 97 | expect(body).to.be.an.object; 98 | done(); 99 | }); 100 | }); 101 | 102 | 103 | it('Update', function (done) { 104 | testrail.updateSuite(1, { 'name': 'This is a new test suite' }, function (err, response, body) { 105 | expect(err).to.be.null; 106 | expect(response).to.be.an.object; 107 | expect(body).to.be.an.object; 108 | done(); 109 | }); 110 | }); 111 | 112 | 113 | it('Delete', function (done) { 114 | testrail.deleteSuite(1, function (err, response, body) { 115 | expect(err).to.be.null; 116 | expect(response).to.be.an.object; 117 | expect(body).to.be.an.object; 118 | done(); 119 | }); 120 | }); 121 | }); 122 | -------------------------------------------------------------------------------- /test/templates.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('templates api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | 14 | nock('https://rundef.testrail.com') 15 | .get(testrail.uri + 'get_templates/1') 16 | .reply(200, [ 17 | { 18 | 'id': 1, 19 | 'is_default': true, 20 | 'name': 'Test Case (Text)' 21 | }, 22 | { 23 | 'id': 2, 24 | 'is_default': false, 25 | 'name': 'Test Case (Steps)' 26 | }, 27 | { 28 | 'id': 3, 29 | 'is_default': false, 30 | 'name': 'Exploratory Session' 31 | } 32 | ]); 33 | 34 | 35 | it('Get all', function (done) { 36 | testrail.getTemplates(1, function (err, response, body) { 37 | expect(err).to.be.null; 38 | expect(response).to.be.an.object; 39 | expect(body).to.be.an.array; 40 | done(); 41 | }); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /test/tests.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('tests api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | nock('https://rundef.testrail.com') 14 | .get(testrail.uri + 'get_test/1') 15 | .reply(200, { 16 | 'assignedto_id': 1, 17 | 'case_id': 1, 18 | 'custom_expected': '..', 19 | 'custom_preconds': '..', 20 | 'custom_steps_separated': [ 21 | { 22 | 'content': 'Step 1', 23 | 'expected': 'Expected Result 1' 24 | }, 25 | { 26 | 'content': 'Step 2', 27 | 'expected': 'Expected Result 2' 28 | } 29 | ], 30 | 'estimate': '1m 5s', 31 | 'estimate_forecast': null, 32 | 'id': 100, 33 | 'priority_id': 2, 34 | 'run_id': 1, 35 | 'status_id': 5, 36 | 'title': 'Verify line spacing on multi-page document', 37 | 'type_id': 4 38 | }); 39 | 40 | nock('https://rundef.testrail.com') 41 | .get(testrail.uri + 'get_test/2') 42 | .reply(400, { 43 | error: 'Field :test is not a valid test.' 44 | }); 45 | 46 | nock('https://rundef.testrail.com') 47 | .get(testrail.uri + 'get_tests/1') 48 | .reply(200, [ 49 | { 50 | 'id': 1, 51 | 'title': 'Test conditional formatting with basic value range' 52 | }, 53 | { 54 | 'id': 2, 55 | 'title': 'Verify line spacing on multi-page document' 56 | } 57 | ]); 58 | 59 | nock('https://rundef.testrail.com') 60 | .get(testrail.uri + 'get_tests/1&status_id='+encodeURIComponent('4,5')) 61 | .reply(200, [ 62 | { 63 | 'id': 1, 64 | 'title': 'Test conditional formatting with basic value range' 65 | }, 66 | { 67 | 'id': 2, 68 | 'title': 'Verify line spacing on multi-page document' 69 | } 70 | ]); 71 | 72 | 73 | 74 | 75 | it('Get one', function (done) { 76 | testrail.getTest(1, function (err, response, body) { 77 | expect(err).to.be.null; 78 | expect(response).to.be.an.object; 79 | expect(body).to.be.an.object; 80 | done(); 81 | }); 82 | }); 83 | 84 | 85 | it('Get one - not found', function (done) { 86 | testrail.getTest(2, function (err, response, body) { 87 | expect(err).to.not.be.null; 88 | expect(response).to.be.an.object; 89 | expect(body).to.be.object; 90 | done(); 91 | }); 92 | }); 93 | 94 | 95 | it('Get all', function (done) { 96 | testrail.getTests(1, function (err, response, body) { 97 | expect(err).to.be.null; 98 | expect(response).to.be.an.object; 99 | expect(body).to.be.an.array; 100 | done(); 101 | }); 102 | }); 103 | 104 | it('Get all - filtered', function (done) { 105 | testrail.getTests(1, { status_id: '4,5' }, function (err, response, body) { 106 | expect(err).to.be.null; 107 | expect(response).to.be.an.object; 108 | expect(body).to.be.an.array; 109 | done(); 110 | }); 111 | }); 112 | }); 113 | -------------------------------------------------------------------------------- /test/users.js: -------------------------------------------------------------------------------- 1 | var Testrail = require('../index'); 2 | 3 | var expect = require('chai').expect; 4 | var nock = require('nock'); 5 | 6 | describe('users api', function() { 7 | var testrail = new Testrail({ 8 | host: 'https://rundef.testrail.com', 9 | user: 'username', 10 | password: 'password' 11 | }); 12 | 13 | nock('https://rundef.testrail.com') 14 | .get(testrail.uri + 'get_user/1') 15 | .reply(200, { 16 | 'email': 'alexis@example.com', 17 | 'id': 1, 18 | 'is_active': true, 19 | 'name': 'Alexis Gonzalez' 20 | }); 21 | 22 | nock('https://rundef.testrail.com') 23 | .get(testrail.uri + 'get_user/2') 24 | .reply(400, { 25 | error: 'Field :user is not a valid user.' 26 | }); 27 | 28 | nock('https://rundef.testrail.com') 29 | .get(testrail.uri + 'get_user_by_email&email='+encodeURIComponent('alexis@example.com')) 30 | .reply(200, { 31 | 'email': 'alexis@example.com', 32 | 'id': 1, 33 | 'is_active': true, 34 | 'name': 'Alexis Gonzalez' 35 | }); 36 | 37 | nock('https://rundef.testrail.com') 38 | .get(testrail.uri + 'get_users') 39 | .reply(200, [ 40 | { 'id': 1, 'name': 'Alexis Gonzalez' }, 41 | { 'id': 2, 'name': 'Ciaran Davenport' } 42 | ]); 43 | 44 | 45 | 46 | 47 | it('Get one', function (done) { 48 | testrail.getUser(1, function (err, response, body) { 49 | expect(err).to.be.null; 50 | expect(response).to.be.an.object; 51 | expect(body).to.be.an.object; 52 | done(); 53 | }); 54 | }); 55 | 56 | 57 | it('Get one - not found', function (done) { 58 | testrail.getUser(2, function (err, response, body) { 59 | expect(err).to.not.be.null; 60 | expect(response).to.be.an.object; 61 | expect(body).to.be.an.object; 62 | done(); 63 | }); 64 | }); 65 | 66 | 67 | it('Get one by email', function (done) { 68 | testrail.getUserByEmail('alexis@example.com', function (err, response, body) { 69 | expect(err).to.be.null; 70 | expect(response).to.be.an.object; 71 | expect(body).to.be.an.object; 72 | done(); 73 | }); 74 | }); 75 | 76 | 77 | it('Get all', function (done) { 78 | testrail.getUsers(function (err, response, body) { 79 | expect(err).to.be.null; 80 | expect(response).to.be.an.object; 81 | expect(body).to.be.an.array; 82 | done(); 83 | }); 84 | }); 85 | }); 86 | --------------------------------------------------------------------------------