@rbaileysr/zephyr-managed-api 1.4.1 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1423 @@
1
+ # Zephyr Managed API - AI Agent Guide
2
+
3
+ > **📋 Purpose**
4
+ >
5
+ > This guide is designed to provide AI coding agents with comprehensive knowledge of the Zephyr Managed API. It covers all available functions, their capabilities, limitations, usage patterns, and best practices.
6
+
7
+ ---
8
+
9
+ ## Table of Contents
10
+
11
+ 1. [Overview](#overview)
12
+ 2. [API Structure](#api-structure)
13
+ 3. [Public API Groups](#public-api-groups)
14
+ 4. [Private API Groups](#private-api-groups)
15
+ 5. [Authentication](#authentication)
16
+ 6. [Error Handling](#error-handling)
17
+ 7. [Common Patterns](#common-patterns)
18
+ 8. [Version Support](#version-support)
19
+ 9. [Limitations and Capabilities](#limitations-and-capabilities)
20
+ 10. [Best Practices](#best-practices)
21
+
22
+ ---
23
+
24
+ ## Overview
25
+
26
+ The Zephyr Managed API is a comprehensive, type-safe wrapper for the Zephyr Scale Cloud REST API v2. It provides hierarchical access to all Zephyr API endpoints, organized into logical groups.
27
+
28
+ ### Key Features
29
+
30
+ - **Type Safety**: Full TypeScript support with IntelliSense
31
+ - **Hierarchical Organization**: Methods organized by entity (TestCase, TestCycle, etc.)
32
+ - **Automatic Retry**: Built-in retry logic for rate limiting (HTTP 429)
33
+ - **Error Handling**: Comprehensive error types and strategies
34
+ - **Private API Support**: Access to unofficial endpoints for advanced functionality
35
+ - **Version Support**: Many methods support version-specific operations
36
+
37
+ ### API Construction
38
+
39
+ ```typescript
40
+ import { createZephyrApi } from '@rbaileysr/zephyr-managed-api';
41
+ import ZephyrApiConnection from './api/zephyr';
42
+
43
+ // Using API Connection (ScriptRunner Connect - recommended)
44
+ const Zephyr = createZephyrApi(ZephyrApiConnection);
45
+
46
+ // Using OAuth Token
47
+ const Zephyr = createZephyrApi('oauth-token', 'https://api.zephyrscale.smartbear.com/v2');
48
+
49
+ // With verbose logging (logs full request/response on failures)
50
+ const Zephyr = createZephyrApi(ZephyrApiConnection, true);
51
+ ```
52
+
53
+ ### Verbose Logging
54
+
55
+ When enabled, verbose logging automatically logs full request and response details whenever an API call fails. This is useful for debugging production issues.
56
+
57
+ **Features:**
58
+ - Logs full request details (method, path, headers, body)
59
+ - Logs full response details (status, headers, body)
60
+ - Automatically sanitizes sensitive headers (authorization, API keys)
61
+ - Only logs on failures (not on successful requests)
62
+
63
+ ---
64
+
65
+ ## API Structure
66
+
67
+ The API is organized into two main categories:
68
+
69
+ 1. **Public API**: Officially supported endpoints from Zephyr
70
+ 2. **Private API**: Unofficial endpoints (use at your own risk)
71
+
72
+ ### Public API Groups
73
+
74
+ - `TestCase` - Test case operations
75
+ - `TestCycle` - Test cycle (test run) operations
76
+ - `TestExecution` - Test execution operations
77
+ - `TestPlan` - Test plan operations
78
+ - `Folder` - Folder operations
79
+ - `Project` - Project operations (read-only)
80
+ - `Status` - Status operations
81
+ - `Priority` - Priority operations
82
+ - `Environment` - Environment operations
83
+ - `Link` - Generic link operations
84
+ - `IssueLink` - Issue link operations
85
+ - `Automation` - Automation operations
86
+
87
+ ### Private API Groups
88
+
89
+ - `Private.Authentication` - Get Context JWT tokens
90
+ - `Private.Comments` - Comment operations
91
+ - `Private.Config` - Configuration operations (Custom Fields, Labels, Iterations, DataSets)
92
+ - `Private.Attachments` - Attachment operations
93
+ - `Private.VersionControl` - Version-specific data operations
94
+ - `Private.TestCase` - Test case private operations (v1.4.0+)
95
+ - `Private.TestCycle` - Test cycle private operations (v1.4.0+)
96
+ - `Private.TestExecution` - Test execution private operations (v1.4.0+)
97
+ - `Private.TestPlan` - Test plan private operations (v1.4.2+)
98
+
99
+ ### Access Pattern
100
+
101
+ ```typescript
102
+ // Public API
103
+ const testCase = await Zephyr.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
104
+
105
+ // Private API
106
+ const comments = await Zephyr.Private.Comments.getTestCaseComments(credentials, {
107
+ testCaseKey: 'PROJ-T1',
108
+ projectId: 12345,
109
+ version: 2 // Optional version support
110
+ });
111
+ ```
112
+
113
+ ---
114
+
115
+ ## Public API Groups
116
+
117
+ ### TestCase Group
118
+
119
+ **Purpose**: Manage test cases - create, read, update, list, and version operations.
120
+
121
+ **Methods:**
122
+
123
+ #### List Operations
124
+ - `listTestCases(options?)` - List all test cases (paginated)
125
+ - Supports filtering by `projectKey`, `folderId`
126
+ - Pagination: `startAt`, `maxResults` (default: 50)
127
+ - Returns: `TestCaseList` with `values`, `total`, `isLast`, etc.
128
+
129
+ - `listTestCasesCursorPaginated(options?)` - List test cases (cursor-based pagination)
130
+ - Better performance for large datasets
131
+ - Pagination: `startAtId`, `limit` (default: 100)
132
+ - Returns: `CursorPagedTestCaseList` with `nextStartAtId`
133
+
134
+ #### Get Operations
135
+ - `getTestCase(options)` - Get a specific test case
136
+ - Required: `testCaseKey` (e.g., 'PROJ-T1')
137
+ - Returns: `TestCase` with all fields
138
+ - Supports error strategy for custom error handling
139
+
140
+ - `getTestCaseVersion(options)` - Get a specific version of a test case
141
+ - Required: `testCaseKey`, `version` (absolute, 1-based)
142
+ - Returns: `TestCase` for that version
143
+ - Use `listTestCaseVersions()` to find available versions
144
+
145
+ - `listTestCaseVersions(options)` - List all versions of a test case
146
+ - Required: `testCaseKey`
147
+ - Returns: `TestCaseVersionLinkList` ordered by most recent first
148
+ - Pagination: `startAt`, `maxResults`
149
+
150
+ #### Create/Update Operations
151
+ - `createTestCase(request)` - Create a new test case
152
+ - Required: `body.projectKey`, `body.name`
153
+ - Optional: `body.folderId`, `body.statusId`, `body.priorityId`, `body.ownerId`, `body.labels`, `body.customFields`, etc.
154
+ - Returns: `KeyedCreatedResource` with `key`, `id`, `self`
155
+
156
+ - `updateTestCase(request)` - Update an existing test case
157
+ - Required: `testCaseKey`, `body` (full TestCase object)
158
+ - **Warning**: Unspecified fields will be cleared
159
+ - Returns: Updated `TestCase`
160
+
161
+ #### Link Operations
162
+ - `getTestCaseLinks(testCaseKey)` - Get all links for a test case
163
+ - Returns: `TestCaseLinkList` with issue links and web links
164
+
165
+ - `createTestCaseIssueLink(request)` - Create issue link
166
+ - Required: `testCaseKey`, `body.issueId`
167
+ - Optional: `body.type` ('COVERAGE', 'BLOCKS', 'RELATED' - defaults to 'COVERAGE')
168
+ - Returns: `CreatedResource` with `id`, `self`
169
+
170
+ - `createTestCaseWebLink(request)` - Create web link
171
+ - Required: `testCaseKey`, `body.url`
172
+ - Optional: `body.description`, `body.type`
173
+ - Returns: `CreatedResource` with `id`, `self`
174
+
175
+ #### Test Script Operations
176
+ - `getTestCaseTestScript(testCaseKey)` - Get test script
177
+ - Returns: `TestScript` with `type` ('PLAIN_TEXT' or 'BDD') and `text`
178
+
179
+ - `createTestCaseTestScript(request)` - Create/update test script
180
+ - Required: `testCaseKey`, `body.type`, `body.text`
181
+ - **Limitation**: Only works with latest version
182
+
183
+ - `getTestCaseTestSteps(testCaseKey)` - Get test steps
184
+ - Returns: `TestStepsList` with array of steps
185
+ - **Limitation**: Does not return step IDs
186
+
187
+ - `createTestCaseTestSteps(request)` - Create/update test steps
188
+ - Required: `testCaseKey`, `body.mode` ('OVERWRITE' or 'APPEND'), `body.items`
189
+ - **Limitation**: Call-to-test steps can only reference latest version
190
+ - **Limitation**: Does not support step IDs for updates
191
+
192
+ **Capabilities:**
193
+ - ✅ Full CRUD operations
194
+ - ✅ Version history access
195
+ - ✅ Link management
196
+ - ✅ Test script and steps management
197
+ - ✅ Pagination (offset and cursor-based)
198
+ - ✅ Error strategy support
199
+
200
+ **Limitations:**
201
+ - ❌ Cannot update older versions directly (use Private API)
202
+ - ❌ Cannot specify version for call-to-test steps (use Private API)
203
+ - ❌ Cannot get step IDs (use Private API)
204
+ - ❌ Cannot delete links (use Private API)
205
+
206
+ ---
207
+
208
+ ### TestCycle Group
209
+
210
+ **Purpose**: Manage test cycles (test runs) - create, read, update, list operations.
211
+
212
+ **Methods:**
213
+
214
+ #### List Operations
215
+ - `listTestCycles(options?)` - List all test cycles (paginated)
216
+ - Supports filtering by `projectKey`, `folderId`, `jiraProjectVersionId`
217
+ - Pagination: `startAt`, `maxResults` (default: 10, max: 1000)
218
+
219
+ #### Get Operations
220
+ - `getTestCycle(options)` - Get a specific test cycle
221
+ - Required: `testCycleIdOrKey` (ID or key like 'PROJ-R1')
222
+ - Returns: `TestCycle` with all fields
223
+
224
+ #### Create/Update Operations
225
+ - `createTestCycle(request)` - Create a new test cycle
226
+ - Required: `body.projectKey`, `body.name`, `body.plannedStartDate`, `body.plannedEndDate`
227
+ - Optional: `body.description`, `body.jiraProjectVersionId`, `body.folderId`, `body.ownerId`, `body.labels`, `body.customFields`
228
+ - Returns: `KeyedCreatedResource`
229
+
230
+ - `updateTestCycle(request)` - Update an existing test cycle
231
+ - Required: `testCycleIdOrKey`, `body` (full TestCycle object)
232
+ - **Warning**: Unspecified fields will be cleared
233
+
234
+ #### Link Operations
235
+ - `getTestCycleLinks(testCycleIdOrKey)` - Get all links for a test cycle
236
+ - `createTestCycleIssueLink(request)` - Create issue link
237
+ - `createTestCycleWebLink(request)` - Create web link
238
+
239
+ **Capabilities:**
240
+ - ✅ Full CRUD operations
241
+ - ✅ Link management
242
+ - ✅ Filtering by project, folder, version
243
+
244
+ **Limitations:**
245
+ - ❌ Cannot delete links (use Private API)
246
+ - ❌ Cannot access iteration data (use Private API)
247
+ - ❌ Cannot get extended data (use Private API)
248
+
249
+ ---
250
+
251
+ ### TestExecution Group
252
+
253
+ **Purpose**: Manage test executions - create, read, update, list operations.
254
+
255
+ **Methods:**
256
+
257
+ #### List Operations
258
+ - `listTestExecutions(options?)` - List test executions (paginated)
259
+ - Supports filtering by `projectKey`, `testCycleKey`, `testCaseKey`, `statusName`, `assignedTo`, `environmentName`
260
+ - Pagination: `startAt`, `maxResults` (default: 50)
261
+
262
+ - `listTestExecutionsNextgen(options?)` - List test executions (cursor-based)
263
+ - Better performance for large datasets
264
+ - Pagination: `startAtId`, `limit` (default: 100)
265
+
266
+ #### Get Operations
267
+ - `getTestExecution(options)` - Get a specific test execution
268
+ - Required: `testExecutionIdOrKey` (ID or key like 'PROJ-E1')
269
+ - Returns: `TestExecution` with all fields
270
+
271
+ #### Create/Update Operations
272
+ - `createTestExecution(request)` - Create a new test execution
273
+ - Required: `body.projectKey`, `body.testCaseKey`, `body.testCycleKey`, `body.statusName`
274
+ - Optional: `body.environmentName`, `body.actualEndDate`, `body.executionTime`, `body.executedById`, `body.assignedToId`, `body.comment`, `body.customFields`, `body.testScriptResults`
275
+ - **Limitation**: Only creates execution against latest test case version
276
+ - Returns: `CreatedResource` (no key returned)
277
+
278
+ - `updateTestExecution(request)` - Update an existing test execution
279
+ - Required: `testExecutionIdOrKey`, `body` (full TestExecution object)
280
+ - **Warning**: Unspecified fields will be cleared
281
+
282
+ #### Test Steps Operations
283
+ - `getTestExecutionTestSteps(testExecutionIdOrKey)` - Get test execution steps
284
+ - Returns: `TestExecutionStepList` with step results
285
+
286
+ - `putTestExecutionTestSteps(request)` - Update test execution steps
287
+ - Required: `testExecutionIdOrKey`, `body.items` (array of step results)
288
+ - **Warning**: Replaces all steps
289
+
290
+ - `syncTestExecutionScript(testExecutionIdOrKey)` - Sync execution steps with test case
291
+ - Automatically updates execution steps to match current test case steps
292
+
293
+ #### Link Operations
294
+ - `listTestExecutionLinks(testExecutionIdOrKey)` - Get all links for a test execution
295
+ - `createTestExecutionIssueLink(request)` - Create issue link
296
+
297
+ **Capabilities:**
298
+ - ✅ Full CRUD operations
299
+ - ✅ Test step result management
300
+ - ✅ Script synchronization
301
+ - ✅ Link management
302
+ - ✅ Filtering and pagination
303
+
304
+ **Limitations:**
305
+ - ❌ Cannot create execution for specific test case version (use Private API)
306
+ - ❌ Cannot create execution with test data (use Private API)
307
+ - ❌ Cannot update step status/comment individually (use Private API)
308
+ - ❌ Cannot access iteration/version data (use Private API)
309
+ - ❌ Cannot list executions across all test case versions (use Private API)
310
+
311
+ ---
312
+
313
+ ### TestPlan Group
314
+
315
+ **Purpose**: Manage test plans - create, read, list operations.
316
+
317
+ **Methods:**
318
+
319
+ #### List Operations
320
+ - `listTestPlans(options?)` - List all test plans (paginated)
321
+ - Supports filtering by `projectKey`
322
+ - Pagination: `startAt`, `maxResults` (default: 10, max: 1000)
323
+
324
+ #### Get Operations
325
+ - `getTestPlan(options)` - Get a specific test plan
326
+ - Required: `testPlanIdOrKey` (ID or key like 'PROJ-P1')
327
+ - Returns: `TestPlan` with all fields
328
+
329
+ #### Create Operations
330
+ - `createTestPlan(request)` - Create a new test plan
331
+ - Required: `body.projectKey`, `body.name`
332
+ - Optional: `body.objective`, `body.folderId`, `body.statusName`, `body.ownerId`, `body.labels`, `body.customFields`
333
+ - Returns: `KeyedCreatedResource`
334
+
335
+ #### Link Operations
336
+ - `createTestPlanIssueLink(request)` - Create issue link
337
+ - `createTestPlanWebLink(request)` - Create web link
338
+ - `createTestPlanTestCycleLink(request)` - Link test cycle to test plan
339
+
340
+ **Capabilities:**
341
+ - ✅ Create and read operations
342
+ - ✅ Link management
343
+
344
+ **Limitations:**
345
+ - ❌ No update operation (test plans are immutable)
346
+ - ❌ Cannot delete links (use Private API)
347
+
348
+ ---
349
+
350
+ ### Folder Group
351
+
352
+ **Purpose**: Manage folders - create, read, list operations.
353
+
354
+ **Methods:**
355
+
356
+ - `listFolders(options?)` - List all folders (paginated)
357
+ - Supports filtering by `projectKey`, `folderType` ('TEST_CASE', 'TEST_CYCLE', 'TEST_PLAN')
358
+ - Pagination: `startAt`, `maxResults`
359
+
360
+ - `getFolder(folderId)` - Get a specific folder
361
+ - Returns: `Folder` with all fields
362
+
363
+ - `createFolder(request)` - Create a new folder
364
+ - Required: `body.projectKey`, `body.name`, `body.folderType`
365
+ - Optional: `body.parentId`
366
+ - Returns: `CreatedResource`
367
+
368
+ **Capabilities:**
369
+ - ✅ Create and read operations
370
+ - ✅ Filtering by project and type
371
+
372
+ **Limitations:**
373
+ - ❌ No update or delete operations
374
+
375
+ ---
376
+
377
+ ### Project Group
378
+
379
+ **Purpose**: Read project information (read-only).
380
+
381
+ **Methods:**
382
+
383
+ - `listProjects(options?)` - List all projects (paginated)
384
+ - Pagination: `startAt`, `maxResults` (default: 10, max: 1000)
385
+
386
+ - `getProject(options)` - Get a specific project
387
+ - Required: `projectIdOrKey`
388
+ - Returns: `Project` with all fields
389
+
390
+ **Capabilities:**
391
+ - ✅ Read-only access to project information
392
+
393
+ **Limitations:**
394
+ - ❌ No create, update, or delete operations
395
+
396
+ ---
397
+
398
+ ### Status Group
399
+
400
+ **Purpose**: Manage test execution statuses.
401
+
402
+ **Methods:**
403
+
404
+ - `listStatuses()` - List all statuses
405
+ - Returns: `StatusList` with all available statuses
406
+
407
+ - `getStatus(statusId)` - Get a specific status
408
+ - Returns: `Status` with all fields
409
+
410
+ - `createStatus(request)` - Create a new status
411
+ - Required: `body.name`, `body.color`
412
+ - Returns: `CreatedResource`
413
+
414
+ - `updateStatus(request)` - Update an existing status
415
+ - Required: `statusId`, `body` (full Status object)
416
+
417
+ **Capabilities:**
418
+ - ✅ Full CRUD operations
419
+
420
+ ---
421
+
422
+ ### Priority Group
423
+
424
+ **Purpose**: Manage test case priorities.
425
+
426
+ **Methods:**
427
+
428
+ - `listPriorities()` - List all priorities
429
+ - `getPriority(priorityId)` - Get a specific priority
430
+ - `createPriority(request)` - Create a new priority
431
+ - `updatePriority(request)` - Update an existing priority
432
+
433
+ **Capabilities:**
434
+ - ✅ Full CRUD operations
435
+
436
+ ---
437
+
438
+ ### Environment Group
439
+
440
+ **Purpose**: Manage test environments.
441
+
442
+ **Methods:**
443
+
444
+ - `listEnvironments()` - List all environments
445
+ - `getEnvironment(environmentId)` - Get a specific environment
446
+ - `createEnvironment(request)` - Create a new environment
447
+ - `updateEnvironment(request)` - Update an existing environment
448
+
449
+ **Capabilities:**
450
+ - ✅ Full CRUD operations
451
+
452
+ ---
453
+
454
+ ### Link Group
455
+
456
+ **Purpose**: Generic link operations.
457
+
458
+ **Methods:**
459
+
460
+ - `getLink(linkId)` - Get a specific link
461
+ - `deleteLink(request)` - Delete a link
462
+ - Required: `linkId`
463
+ - **Note**: This is a public API method, but only works for certain link types
464
+
465
+ **Capabilities:**
466
+ - ✅ Read and delete operations
467
+
468
+ **Limitations:**
469
+ - ❌ Cannot create links (use specific group methods)
470
+ - ❌ Delete may not work for all link types (use Private API)
471
+
472
+ ---
473
+
474
+ ### IssueLink Group
475
+
476
+ **Purpose**: Issue link operations.
477
+
478
+ **Methods:**
479
+
480
+ - `getIssueLinkTestCases(issueKey)` - Get test cases linked to an issue
481
+ - `getIssueLinkTestCycles(issueKey)` - Get test cycles linked to an issue
482
+ - `getIssueLinkTestPlans(issueKey)` - Get test plans linked to an issue
483
+ - `getIssueLinkTestExecutions(issueKey)` - Get test executions linked to an issue
484
+
485
+ **Capabilities:**
486
+ - ✅ Query links by issue key
487
+
488
+ ---
489
+
490
+ ### Automation Group
491
+
492
+ **Purpose**: Automation-related operations.
493
+
494
+ **Methods:**
495
+
496
+ - `getAutomationExecutions(options)` - Get automation executions
497
+ - Supports filtering by `projectKey`, `testCaseKey`, `testCycleKey`, `statusName`
498
+ - Pagination: `startAt`, `maxResults`
499
+
500
+ **Capabilities:**
501
+ - ✅ Query automation execution data
502
+
503
+ ---
504
+
505
+ ## Private API Groups
506
+
507
+ ⚠️ **WARNING**: Private API methods use Zephyr's unofficial endpoints that are:
508
+ - Not officially supported by SmartBear
509
+ - Not part of the public API documentation
510
+ - Subject to change at any time without notice
511
+ - Not covered by Standard Support
512
+
513
+ Use these methods at your own risk.
514
+
515
+ ### Authentication
516
+
517
+ **Purpose**: Get Jira Context JWT tokens required for all private API calls.
518
+
519
+ **Methods:**
520
+
521
+ - `getContextJwt(credentials)` - Get Context JWT token
522
+ - Required: `credentials.userEmail`, `credentials.apiToken`, `credentials.jiraInstanceUrl`
523
+ - Returns: JWT token string
524
+ - **Token expires after 15 minutes** - tokens are automatically retrieved internally
525
+ - **Note**: This method is called automatically by other private API methods
526
+
527
+ - `enableZephyrForProject(credentials, request)` - Enable Zephyr for a Jira project
528
+ - Required: `request.projectId`
529
+
530
+ - `isZephyrEnabledForProject(credentials, request)` - Check if Zephyr is enabled
531
+ - Required: `request.projectId`
532
+ - Returns: Boolean
533
+
534
+ **Capabilities:**
535
+ - ✅ Get authentication tokens
536
+ - ✅ Project enablement checks
537
+
538
+ **Limitations:**
539
+ - ❌ Tokens expire after 15 minutes (handled automatically)
540
+
541
+ ---
542
+
543
+ ### Comments
544
+
545
+ **Purpose**: Manage comments on test cases, test cycles, and test plans.
546
+
547
+ **Methods:**
548
+
549
+ #### Test Case Comments
550
+ - `getTestCaseComments(credentials, request)` - Get all comments for a test case
551
+ - Required: `testCaseKey`, `projectId`
552
+ - Optional: `version` (absolute, 1-based) - if not provided, uses latest version
553
+ - Returns: `PrivateComment[]`
554
+
555
+ - `createTestCaseComment(credentials, request)` - Create a comment on a test case
556
+ - Required: `testCaseKey`, `projectId`, `body`, `createdBy`
557
+ - Optional: `version` (v1.4.2+) - if not provided, uses latest version
558
+ - Returns: `CreateTestCaseCommentResponse`
559
+
560
+ - `deleteTestCaseComment(credentials, request)` - Delete a comment (v1.4.2+)
561
+ - Required: `testCaseKey`, `projectId`, `commentId`
562
+ - Optional: `version` - if not provided, uses latest version
563
+ - Returns: `void`
564
+
565
+ #### Test Cycle Comments
566
+ - `getTestCycleComments(credentials, request)` - Get all comments for a test cycle
567
+ - `createTestCycleComment(credentials, request)` - Create a comment on a test cycle
568
+ - `deleteTestCycleComment(credentials, request)` - Delete a comment (v1.4.2+)
569
+
570
+ #### Test Plan Comments
571
+ - `getTestPlanComments(credentials, request)` - Get all comments for a test plan
572
+ - `createTestPlanComment(credentials, request)` - Create a comment on a test plan
573
+ - `deleteTestPlanComment(credentials, request)` - Delete a comment (v1.4.2+)
574
+
575
+ **Capabilities:**
576
+ - ✅ Full CRUD operations for comments
577
+ - ✅ Version support for test case comments
578
+ - ✅ Access to comment metadata (createdBy, createdOn)
579
+
580
+ **Limitations:**
581
+ - ❌ Cannot update comments (only create/delete)
582
+ - ❌ Cannot get comments for specific test execution steps (not available)
583
+
584
+ ---
585
+
586
+ ### Attachments
587
+
588
+ **Purpose**: Manage attachments on test cases, test cycles, test plans, test steps, and test executions.
589
+
590
+ **Methods:**
591
+
592
+ #### Test Case Attachments
593
+ - `getTestCaseAttachments(credentials, request)` - Get all attachments for a test case
594
+ - Required: `testCaseKey`, `projectId`
595
+ - Optional: `version` - if not provided, uses latest version
596
+ - Returns: `GetTestCaseAttachmentsResponse` with signed S3 URLs
597
+
598
+ - `downloadAttachment(credentials, request)` - Download an attachment into memory
599
+ - Required: `testCaseKey`, `projectId`, `attachmentId`
600
+ - Optional: `version` - if not provided, uses latest version
601
+ - Returns: `Blob` with file content
602
+
603
+ - `createTestCaseAttachment(credentials, request)` - Upload an attachment to a test case
604
+ - Required: `testCaseKey`, `projectId`, `file` (Blob or ArrayBuffer), `fileName`, `userAccountId`
605
+ - Optional: `version` (v1.4.2+) - if not provided, uses latest version
606
+ - Returns: `UploadDetailsResponse`
607
+
608
+ - `deleteTestCaseAttachment(credentials, request)` - Delete an attachment (v1.4.2+)
609
+ - Required: `projectId`, `attachmentId`
610
+ - Optional: `testCaseKey`, `version` - for version-specific attachments
611
+
612
+ #### Test Step Attachments
613
+ - `getTestStepAttachments(credentials, request)` - Get attachments for a test step
614
+ - `downloadTestStepAttachment(credentials, request)` - Download test step attachment
615
+ - `createTestStepAttachment(credentials, request)` - Upload attachment to test step
616
+ - Optional: `version` (v1.4.2+) - for version-specific test steps
617
+ - `deleteTestStepAttachment(credentials, request)` - Delete test step attachment (v1.4.2+)
618
+ - Optional: `version` - for version-specific test steps
619
+
620
+ #### Test Cycle Attachments
621
+ - `getTestCycleAttachments(credentials, request)` - Get all attachments for a test cycle
622
+ - `downloadTestCycleAttachment(credentials, request)` - Download test cycle attachment
623
+ - `createTestCycleAttachment(credentials, request)` - Upload attachment to test cycle
624
+ - `deleteTestCycleAttachment(credentials, request)` - Delete test cycle attachment (v1.4.2+)
625
+
626
+ #### Test Plan Attachments
627
+ - `getTestPlanAttachments(credentials, request)` - Get all attachments for a test plan
628
+ - `downloadTestPlanAttachment(credentials, request)` - Download test plan attachment
629
+ - `createTestPlanAttachment(credentials, request)` - Upload attachment to test plan
630
+ - `deleteTestPlanAttachment(credentials, request)` - Delete test plan attachment (v1.4.2+)
631
+
632
+ #### Test Execution Attachments
633
+ - `getTestExecutionAttachments(credentials, request)` - Get all attachments for a test execution
634
+ - `downloadTestExecutionAttachment(credentials, request)` - Download test execution attachment
635
+ - `createTestExecutionAttachment(credentials, request)` - Upload attachment to test execution
636
+
637
+ #### Test Execution Step Attachments
638
+ - `getTestExecutionStepAttachments(credentials, request)` - Get attachments for a test execution step
639
+ - `downloadTestExecutionStepAttachment(credentials, request)` - Download test execution step attachment
640
+ - `createTestExecutionStepAttachment(credentials, request)` - Upload attachment to test execution step
641
+
642
+ **Capabilities:**
643
+ - ✅ Full CRUD operations for attachments
644
+ - ✅ Version support for test case and test step attachments
645
+ - ✅ Signed S3 URLs for secure downloads
646
+ - ✅ Support for all attachment types (images, PDFs, documents, etc.)
647
+
648
+ **Limitations:**
649
+ - ❌ Cannot update attachment metadata (only create/delete)
650
+ - ❌ File size limits apply (check Zephyr documentation)
651
+
652
+ ---
653
+
654
+ ### Config
655
+
656
+ **Purpose**: Manage configuration items (Custom Fields, Labels, Iterations, DataSets).
657
+
658
+ **Methods:**
659
+
660
+ #### Custom Fields
661
+ - `createCustomField(credentials, request)` - Create a custom field
662
+ - Required: `request.body.name`, `request.body.category` ('TEST_CASE', 'TEST_CYCLE', 'TEST_PLAN', 'TEST_EXECUTION')
663
+ - Optional: `request.body.fieldType`, `request.body.options`, etc.
664
+ - Returns: `CreatedResource`
665
+
666
+ - `getCustomFields(credentials, request)` - Get all custom fields
667
+ - Required: `request.category`
668
+ - Returns: Array of custom field definitions
669
+
670
+ #### Labels
671
+ - `getLabels(credentials, request)` - Get all labels
672
+ - `createLabel(credentials, request)` - Create a new label
673
+
674
+ #### Iterations
675
+ - `getIterations(credentials, request)` - Get all iterations
676
+ - `createIteration(credentials, request)` - Create a new iteration
677
+
678
+ #### DataSets
679
+ - `getDataSets(credentials, request)` - Get all data sets
680
+ - `createDataSet(credentials, request)` - Create a new data set
681
+ - `updateDataSet(credentials, request)` - Update an existing data set
682
+
683
+ #### Archive Operations
684
+ - `archiveConfig(credentials, request)` - Archive a config item
685
+ - `unarchiveConfig(credentials, request)` - Unarchive a config item
686
+
687
+ **Capabilities:**
688
+ - ✅ Full CRUD operations for configuration
689
+ - ✅ Archive/unarchive support
690
+
691
+ ---
692
+
693
+ ### VersionControl
694
+
695
+ **Purpose**: Get version-specific data (links, test scripts, test steps).
696
+
697
+ **Methods:**
698
+
699
+ #### Test Case Version-Specific Operations
700
+ - `getTestCaseIssueLinks(credentials, request)` - Get issue links for a specific version
701
+ - Required: `testCaseKey`, `projectId`
702
+ - Optional: `version` - if not provided, uses latest version
703
+ - Returns: Array of issue links
704
+
705
+ - `getTestCaseWebLinks(credentials, request)` - Get web links for a specific version
706
+ - Required: `testCaseKey`, `projectId`
707
+ - Optional: `version` - if not provided, uses latest version
708
+ - Returns: Array of web links
709
+
710
+ - `getTestCaseTestScript(credentials, request)` - Get test script for a specific version
711
+ - Required: `testCaseKey`, `projectId`
712
+ - Optional: `version` - if not provided, uses latest version
713
+ - Returns: `TestScript` or `null`
714
+
715
+ - `getTestCaseTestSteps(credentials, request)` - Get test steps for a specific version
716
+ - Required: `testCaseKey`, `projectId`
717
+ - Optional: `version` - if not provided, uses latest version
718
+ - Returns: `TestStepsList`
719
+
720
+ #### Test Execution Step Operations
721
+ - `getTestExecutionStepIssueLinks(credentials, request)` - Get issue links for a test execution step
722
+ - `createTestExecutionStepIssueLink(credentials, request)` - Create issue link for a test execution step
723
+
724
+ **Capabilities:**
725
+ - ✅ Version-specific data access
726
+ - ✅ Historical data retrieval
727
+
728
+ **Limitations:**
729
+ - ❌ Cannot modify version-specific data (only read)
730
+
731
+ ---
732
+
733
+ ### TestCase (Entity-Based Group - v1.4.0+)
734
+
735
+ **Purpose**: Consolidates all test case-related private API operations.
736
+
737
+ **Sub-groups:**
738
+
739
+ #### Archiving
740
+ - `getArchivedTestCases(credentials, request)` - List archived test cases
741
+ - `archiveTestCases(credentials, request)` - Archive test cases
742
+ - `unarchiveTestCases(credentials, request)` - Unarchive test cases
743
+
744
+ #### TestScriptData
745
+ - `setTestCaseParamTypeToParameter(credentials, request)` - Set param type to PARAMETER
746
+ - Optional: `version` (v1.4.2+) - if not provided, uses latest version
747
+
748
+ - `setTestCaseParameters(credentials, request)` - Set test case parameters
749
+ - Required: `parameters` array
750
+ - Optional: `version` (v1.4.2+) - if not provided, uses latest version
751
+
752
+ - `setTestCaseParamTypeToTestData(credentials, request)` - Set param type to TEST_DATA
753
+ - Optional: `version` (v1.4.2+) - if not provided, uses latest version
754
+
755
+ - `setTestCaseTestData(credentials, request)` - Set test data rows
756
+ - Required: `testData` array (array of column objects)
757
+ - Optional: `version` (v1.4.2+) - if not provided, uses latest version
758
+
759
+ - `getTestCaseTestData(credentials, request)` - Get test data
760
+ - Optional: `version` (v1.4.2+) - if not provided, uses latest version
761
+ - Returns: `TestCaseTestDataResponse` with `paramType`, `parameters`, `testData`
762
+
763
+ - `hasTestCaseTestData(credentials, request)` - Check if test case has test data
764
+ - Optional: `version` (v1.4.2+) - if not provided, uses latest version
765
+ - Returns: `HasTestCaseTestDataResponse` with `hasData` boolean
766
+
767
+ #### Versions
768
+ - `createTestCaseVersion(credentials, request)` - Create a new test case version
769
+ - Required: `testCaseKey`, `projectId`
770
+ - Returns: `CreateTestCaseVersionResponse` with new version number
771
+
772
+ #### Methods
773
+ - `getTestCaseTestStepsWithIds(credentials, request)` - Get test steps with IDs (v1.4.1+)
774
+ - Required: `testCaseKey`, `projectId`
775
+ - Optional: `version` - if not provided, uses latest version
776
+ - Returns: `GetTestCaseTestStepsWithIdsResponse` with `testScriptId`, `stepByStepScriptId`, `steps` (with IDs)
777
+ - **Key Feature**: Includes step IDs needed for updates, and call-to-test step information with test case IDs and versions
778
+
779
+ - `createTestCaseTestStepsWithVersion(credentials, request)` - Create/update test steps with version support (v1.4.1+)
780
+ - Required: `testCaseKey`, `projectId`, `body.mode` ('OVERWRITE' or 'APPEND'), `body.items`
781
+ - Optional: `version` (v1.4.2+) - version for the test case itself
782
+ - Optional: `version` in `body.items[].testCase` - version for call-to-test steps
783
+ - **Key Feature**: Allows specifying version for call-to-test steps, enabling references to older test case versions
784
+ - **Key Feature**: Supports step IDs for updating existing steps
785
+ - Returns: `void`
786
+
787
+ - `updateTestCasePlainTextScriptWithVersion(credentials, request)` - Update plain text script for a version (v1.4.2+)
788
+ - Required: `testCaseKey`, `projectId`, `scriptId`, `text`
789
+ - Optional: `version` - if not provided, uses latest version
790
+ - Returns: `void`
791
+
792
+ - `updateTestCaseBddScriptWithVersion(credentials, request)` - Update BDD script for a version (v1.4.2+)
793
+ - Required: `testCaseKey`, `projectId`, `scriptId`, `text`
794
+ - Optional: `version` - if not provided, uses latest version
795
+ - Returns: `void`
796
+
797
+ - `deleteTestCaseWebLink(credentials, request)` - Delete web link (v1.4.2+)
798
+ - Required: `testCaseKey`, `projectId`, `linkId`
799
+ - Optional: `version` - if not provided, uses latest version
800
+ - Returns: `void`
801
+
802
+ - `deleteTestCaseIssueLink(credentials, request)` - Delete issue link (v1.4.2+)
803
+ - Required: `testCaseKey`, `projectId`, `linkId`
804
+ - Optional: `version` - if not provided, uses latest version
805
+ - Returns: `void`
806
+
807
+ **Capabilities:**
808
+ - ✅ Version-specific operations
809
+ - ✅ Test script data management (parameters/test data)
810
+ - ✅ Test step management with IDs
811
+ - ✅ Call-to-test steps with version support
812
+ - ✅ Link deletion
813
+ - ✅ Archiving operations
814
+
815
+ **Limitations:**
816
+ - ❌ Cannot delete test cases (only archive)
817
+ - ❌ Cannot modify test case metadata for older versions (only test script data)
818
+
819
+ ---
820
+
821
+ ### TestCycle (Entity-Based Group - v1.4.0+)
822
+
823
+ **Purpose**: Extended data operations for test cycles.
824
+
825
+ **Sub-groups:**
826
+
827
+ #### ExtendedData
828
+ - `getTestCycleIteration(credentials, request)` - Get iteration for a test cycle
829
+ - Required: `testCycleKey`, `projectId`
830
+ - Returns: `TestCycleIterationResponse` with `id`, `key`, `iterationId`
831
+
832
+ - `updateTestCycleIteration(credentials, request)` - Update iteration for a test cycle
833
+ - Required: `testCycleKey`, `projectId`, `iterationId`
834
+ - Returns: `void`
835
+
836
+ #### Methods
837
+ - `deleteTestCycleWebLink(credentials, request)` - Delete web link (v1.4.2+)
838
+ - Required: `testCycleKey`, `projectId`, `linkId`
839
+ - Returns: `void`
840
+
841
+ - `deleteTestCycleIssueLink(credentials, request)` - Delete issue link (v1.4.2+)
842
+ - Required: `testCycleKey`, `projectId`, `linkId`
843
+ - Returns: `void`
844
+
845
+ **Capabilities:**
846
+ - ✅ Iteration management
847
+ - ✅ Link deletion
848
+
849
+ **Limitations:**
850
+ - ❌ Cannot access other extended data fields
851
+
852
+ ---
853
+
854
+ ### TestExecution (Entity-Based Group - v1.4.0+)
855
+
856
+ **Purpose**: All test execution-related private API operations.
857
+
858
+ **Sub-groups:**
859
+
860
+ #### ExtendedData
861
+ - `getTestExecutionIteration(credentials, request)` - Get iteration for a test execution
862
+ - `updateTestExecutionIteration(credentials, request)` - Update iteration for a test execution
863
+ - `getTestExecutionVersion(credentials, request)` - Get Jira version for a test execution
864
+ - `updateTestExecutionVersion(credentials, request)` - Update Jira version for a test execution
865
+
866
+ #### Methods
867
+ - `listAllTestExecutionsForTestCase(credentials, request)` - List executions across all versions (v1.4.1+)
868
+ - Required: `testCaseKey`, `projectId`
869
+ - Optional: `offset`, `limit` (pagination)
870
+ - Returns: `ListAllTestExecutionsForTestCaseResponse` with `data` (minimal: `key`, `testCase`) and `totalCount`
871
+ - **Key Feature**: Returns executions from all test case versions, not just latest
872
+ - **Note**: Returns minimal data - use public API to get full execution details
873
+
874
+ - `createTestExecutionWithTestData(credentials, request)` - Create execution with test data
875
+ - Required: `body` (TestExecutionInput), `projectId`
876
+ - Optional: `testData` (array of parameter values)
877
+ - Returns: `CreatedResource`
878
+
879
+ - `createTestExecutionWithVersion(credentials, request)` - Create execution for specific version (v1.4.1+)
880
+ - Required: `body.testCaseKey`, `body.testCycleKey`, `body.statusName`, `body.version`, `projectId`
881
+ - Optional: `body.environmentName`, `body.actualEndDate`, `body.executionTime`, `body.executedById`, `body.assignedToId`, `body.comment`, `body.customFields`, `assignedTo`, `iterationId`, `jiraVersionId`
882
+ - Returns: `CreateTestExecutionWithVersionResponse` with `id` and `key`
883
+ - **Key Feature**: Creates execution against a specific test case version, not just latest
884
+
885
+ - `updateTestExecution(credentials, request)` - Update test execution
886
+ - Required: `testExecutionKey`, `body` (full TestExecution object)
887
+ - Returns: `void`
888
+
889
+ - `getTestExecutionSteps(credentials, request)` - Get test execution steps
890
+ - Returns: Array of step results with full details
891
+
892
+ - `updateTestExecutionStepStatus(credentials, request)` - Update individual step status
893
+ - Required: `testExecutionKey`, `stepIndex`, `statusName`, `projectId`
894
+ - Returns: `void`
895
+
896
+ - `updateTestExecutionStepComment(credentials, request)` - Update individual step comment
897
+ - Required: `testExecutionKey`, `stepIndex`, `comment`, `projectId`
898
+ - Returns: `void`
899
+
900
+ - `getTestCycleItems(credentials, request)` - Get all items in a test cycle
901
+ - Required: `testCycleKey`, `projectId`
902
+ - Returns: Array of test execution summaries
903
+
904
+ **Capabilities:**
905
+ - ✅ Version-specific execution creation
906
+ - ✅ Test data support
907
+ - ✅ Individual step updates
908
+ - ✅ Iteration and version management
909
+ - ✅ List executions across all versions
910
+
911
+ **Limitations:**
912
+ - ❌ Cannot delete test executions (immutable)
913
+ - ❌ Cannot update execution for older test case versions
914
+
915
+ ---
916
+
917
+ ### TestPlan (Entity-Based Group - v1.4.2+)
918
+
919
+ **Purpose**: Private API operations for test plans.
920
+
921
+ **Methods:**
922
+
923
+ - `deleteTestPlanWebLink(credentials, request)` - Delete web link
924
+ - Required: `testPlanKey`, `projectId`, `linkId`
925
+ - Returns: `void`
926
+
927
+ - `deleteTestPlanIssueLink(credentials, request)` - Delete issue link
928
+ - Required: `testPlanKey`, `projectId`, `linkId`
929
+ - Returns: `void`
930
+
931
+ **Capabilities:**
932
+ - ✅ Link deletion
933
+
934
+ **Limitations:**
935
+ - ❌ Limited operations (test plans are mostly immutable)
936
+
937
+ ---
938
+
939
+ ## Authentication
940
+
941
+ ### Public API Authentication
942
+
943
+ Public API methods use OAuth tokens or API Connections (ScriptRunner Connect).
944
+
945
+ **OAuth Token:**
946
+ ```typescript
947
+ const Zephyr = createZephyrApi('oauth-token', 'https://api.zephyrscale.smartbear.com/v2');
948
+ ```
949
+
950
+ **API Connection (ScriptRunner Connect):**
951
+ ```typescript
952
+ import ZephyrApiConnection from './api/zephyr';
953
+ const Zephyr = createZephyrApi(ZephyrApiConnection);
954
+ ```
955
+
956
+ ### Private API Authentication
957
+
958
+ All private API methods require `PrivateApiCredentials`:
959
+
960
+ ```typescript
961
+ interface PrivateApiCredentials {
962
+ userEmail: string; // Jira user email
963
+ apiToken: string; // Jira API token
964
+ jiraInstanceUrl: string; // Full Jira instance URL (e.g., 'https://your-instance.atlassian.net')
965
+ }
966
+ ```
967
+
968
+ **Example:**
969
+ ```typescript
970
+ const credentials = {
971
+ userEmail: 'user@example.com',
972
+ apiToken: 'your-api-token',
973
+ jiraInstanceUrl: 'https://your-instance.atlassian.net'
974
+ };
975
+
976
+ const comments = await Zephyr.Private.Comments.getTestCaseComments(credentials, {
977
+ testCaseKey: 'PROJ-T1',
978
+ projectId: 12345
979
+ });
980
+ ```
981
+
982
+ **Important Notes:**
983
+ - Context JWT tokens expire after 15 minutes
984
+ - Tokens are automatically retrieved internally by private API methods
985
+ - You don't need to call `getContextJwt()` manually unless you need the token for custom operations
986
+
987
+ ---
988
+
989
+ ## Error Handling
990
+
991
+ ### Error Types
992
+
993
+ The API uses comprehensive error types from `@managed-api/commons-core`:
994
+
995
+ - `BadRequestError` (400) - Invalid request parameters
996
+ - `UnauthorizedError` (401) - Authentication failed
997
+ - `ForbiddenError` (403) - Insufficient permissions
998
+ - `NotFoundError` (404) - Resource not found
999
+ - `TooManyRequestsError` (429) - Rate limited (automatically retried)
1000
+ - `ServerError` (500+) - Server errors
1001
+ - `UnexpectedError` - Network errors, JSON parsing errors, etc.
1002
+
1003
+ ### Default Behavior
1004
+
1005
+ - **Automatic Retry**: Rate limiting (429) is automatically retried with exponential backoff
1006
+ - **Error Throwing**: All errors are thrown as exceptions
1007
+ - **Error Logging**: Uncaught errors are logged by the ScriptRunner Connect runtime
1008
+
1009
+ ### Error Strategy
1010
+
1011
+ Public API methods support optional error strategy for custom error handling:
1012
+
1013
+ ```typescript
1014
+ import { retry, continuePropagation } from '@managed-api/commons-core';
1015
+
1016
+ // Return null on 404 instead of throwing
1017
+ const testCase = await Zephyr.TestCase.getTestCase(
1018
+ { testCaseKey: 'PROJ-T1' },
1019
+ {
1020
+ handleHttp404Error: () => ({ type: 'return', value: null })
1021
+ }
1022
+ );
1023
+
1024
+ // Retry on rate limiting with custom delay
1025
+ const testCase = await Zephyr.TestCase.getTestCase(
1026
+ { testCaseKey: 'PROJ-T1' },
1027
+ {
1028
+ handleHttp429Error: (response, retryCount) => retry(2000)
1029
+ }
1030
+ );
1031
+ ```
1032
+
1033
+ **Private API Methods:**
1034
+ - Do not support error strategy (always throw errors)
1035
+ - Use try/catch blocks for error handling
1036
+
1037
+ ---
1038
+
1039
+ ## Common Patterns
1040
+
1041
+ ### Pagination
1042
+
1043
+ #### Offset-Based Pagination
1044
+ ```typescript
1045
+ let startAt = 0;
1046
+ const maxResults = 50;
1047
+ let allTestCases = [];
1048
+
1049
+ while (true) {
1050
+ const page = await Zephyr.TestCase.listTestCases({
1051
+ startAt,
1052
+ maxResults
1053
+ });
1054
+
1055
+ allTestCases.push(...page.values);
1056
+
1057
+ if (page.isLast) break;
1058
+ startAt += maxResults;
1059
+ }
1060
+ ```
1061
+
1062
+ #### Cursor-Based Pagination
1063
+ ```typescript
1064
+ let startAtId: number | null = null;
1065
+ const limit = 100;
1066
+ let allTestCases = [];
1067
+
1068
+ while (true) {
1069
+ const page = await Zephyr.TestCase.listTestCasesCursorPaginated({
1070
+ startAtId,
1071
+ limit
1072
+ });
1073
+
1074
+ allTestCases.push(...page.values);
1075
+
1076
+ if (!page.nextStartAtId) break;
1077
+ startAtId = page.nextStartAtId;
1078
+ }
1079
+ ```
1080
+
1081
+ ### Version Operations
1082
+
1083
+ ```typescript
1084
+ // Get all versions
1085
+ const versions = await Zephyr.TestCase.listTestCaseVersions({
1086
+ testCaseKey: 'PROJ-T1'
1087
+ });
1088
+
1089
+ // Get specific version
1090
+ const version2 = await Zephyr.TestCase.getTestCaseVersion({
1091
+ testCaseKey: 'PROJ-T1',
1092
+ version: 2
1093
+ });
1094
+
1095
+ // Create new version
1096
+ const newVersion = await Zephyr.Private.TestCase.Versions.createTestCaseVersion(
1097
+ credentials,
1098
+ {
1099
+ testCaseKey: 'PROJ-T1',
1100
+ projectId: 12345
1101
+ }
1102
+ );
1103
+ ```
1104
+
1105
+ ### Test Steps with Version Support
1106
+
1107
+ ```typescript
1108
+ // Get steps with IDs
1109
+ const steps = await Zephyr.Private.TestCase.getTestCaseTestStepsWithIds(
1110
+ credentials,
1111
+ {
1112
+ testCaseKey: 'PROJ-T1',
1113
+ projectId: 12345,
1114
+ version: 2 // Optional: get steps for version 2
1115
+ }
1116
+ );
1117
+
1118
+ // Create steps with version support for call-to-test
1119
+ await Zephyr.Private.TestCase.createTestCaseTestStepsWithVersion(
1120
+ credentials,
1121
+ {
1122
+ testCaseKey: 'PROJ-T1',
1123
+ projectId: 12345,
1124
+ version: 2, // Optional: update steps for version 2
1125
+ body: {
1126
+ mode: 'APPEND',
1127
+ items: [
1128
+ {
1129
+ inline: {
1130
+ description: 'Step 1',
1131
+ expectedResult: 'Result 1'
1132
+ }
1133
+ },
1134
+ {
1135
+ testCase: {
1136
+ testCaseKey: 'PROJ-T2',
1137
+ version: 1 // Reference version 1 of PROJ-T2
1138
+ }
1139
+ }
1140
+ ]
1141
+ }
1142
+ }
1143
+ );
1144
+ ```
1145
+
1146
+ ### Creating Test Executions
1147
+
1148
+ ```typescript
1149
+ // Public API - latest version only
1150
+ const execution = await Zephyr.TestExecution.createTestExecution({
1151
+ body: {
1152
+ projectKey: 'PROJ',
1153
+ testCaseKey: 'PROJ-T1',
1154
+ testCycleKey: 'PROJ-R1',
1155
+ statusName: 'Not Executed'
1156
+ }
1157
+ });
1158
+
1159
+ // Private API - specific version
1160
+ const executionV2 = await Zephyr.Private.TestExecution.createTestExecutionWithVersion(
1161
+ credentials,
1162
+ {
1163
+ body: {
1164
+ projectKey: 'PROJ',
1165
+ testCaseKey: 'PROJ-T1',
1166
+ testCycleKey: 'PROJ-R1',
1167
+ statusName: 'Not Executed',
1168
+ version: 2 // Create execution for version 2
1169
+ },
1170
+ projectId: 12345
1171
+ }
1172
+ );
1173
+ ```
1174
+
1175
+ ---
1176
+
1177
+ ## Version Support
1178
+
1179
+ ### Version Numbering
1180
+
1181
+ Versions are **absolute, 1-based**:
1182
+ - Version 1 = First version ever created
1183
+ - Version 2 = Second version created
1184
+ - Highest number = Current/latest version
1185
+
1186
+ ### Finding Versions
1187
+
1188
+ ```typescript
1189
+ // List all versions
1190
+ const versions = await Zephyr.TestCase.listTestCaseVersions({
1191
+ testCaseKey: 'PROJ-T1'
1192
+ });
1193
+
1194
+ // Latest version is the one with highest majorVersion
1195
+ const latestVersion = versions.values[0]; // Most recent first
1196
+ ```
1197
+
1198
+ ### Methods with Version Support
1199
+
1200
+ **Public API:**
1201
+ - `getTestCaseVersion()` - Get specific version
1202
+ - `listTestCaseVersions()` - List all versions
1203
+
1204
+ **Private API (v1.4.2+):**
1205
+ Most test case-related methods support optional `version` parameter:
1206
+ - `getTestCaseComments()` - Get comments for a version
1207
+ - `createTestCaseComment()` - Create comment on a version
1208
+ - `deleteTestCaseComment()` - Delete comment from a version
1209
+ - `getTestCaseAttachments()` - Get attachments for a version
1210
+ - `createTestCaseAttachment()` - Upload attachment to a version
1211
+ - `deleteTestCaseAttachment()` - Delete attachment from a version
1212
+ - `getTestCaseTestStepsWithIds()` - Get steps for a version
1213
+ - `createTestCaseTestStepsWithVersion()` - Update steps for a version
1214
+ - `setTestCaseParamTypeToParameter()` - Set param type for a version
1215
+ - `setTestCaseParameters()` - Set parameters for a version
1216
+ - `setTestCaseParamTypeToTestData()` - Set param type for a version
1217
+ - `setTestCaseTestData()` - Set test data for a version
1218
+ - `getTestCaseTestData()` - Get test data for a version
1219
+ - `hasTestCaseTestData()` - Check test data for a version
1220
+ - `updateTestCasePlainTextScriptWithVersion()` - Update plain text script for a version
1221
+ - `updateTestCaseBddScriptWithVersion()` - Update BDD script for a version
1222
+ - `deleteTestCaseWebLink()` - Delete web link from a version
1223
+ - `deleteTestCaseIssueLink()` - Delete issue link from a version
1224
+ - `getTestStepAttachments()` - Get attachments for a version
1225
+ - `createTestStepAttachment()` - Upload attachment to a version
1226
+ - `deleteTestStepAttachment()` - Delete attachment from a version
1227
+
1228
+ **Version Resolution:**
1229
+ - If `version` is provided and > 0: Uses that specific version
1230
+ - If `version` is undefined or 0: Uses latest version
1231
+ - Version resolution happens automatically via `getTestCaseVersion()` or `getTestCase()`
1232
+
1233
+ ---
1234
+
1235
+ ## Limitations and Capabilities
1236
+
1237
+ ### Public API Limitations
1238
+
1239
+ **Test Cases:**
1240
+ - ❌ Cannot update older versions directly
1241
+ - ❌ Cannot specify version for call-to-test steps
1242
+ - ❌ Cannot get step IDs
1243
+ - ❌ Cannot delete links
1244
+ - ❌ Cannot update test scripts for older versions
1245
+
1246
+ **Test Executions:**
1247
+ - ❌ Cannot create execution for specific test case version
1248
+ - ❌ Cannot create execution with test data
1249
+ - ❌ Cannot update step status/comment individually
1250
+ - ❌ Cannot list executions across all versions
1251
+ - ❌ Cannot access iteration/version data
1252
+
1253
+ **Test Cycles:**
1254
+ - ❌ Cannot delete links
1255
+ - ❌ Cannot access iteration data
1256
+
1257
+ **Test Plans:**
1258
+ - ❌ No update operation (immutable)
1259
+ - ❌ Cannot delete links
1260
+
1261
+ ### Private API Capabilities
1262
+
1263
+ **Test Cases:**
1264
+ - ✅ Version-specific operations
1265
+ - ✅ Test script data management (parameters/test data)
1266
+ - ✅ Test step management with IDs
1267
+ - ✅ Call-to-test steps with version support
1268
+ - ✅ Link deletion
1269
+ - ✅ Archiving operations
1270
+ - ✅ Comment and attachment management with version support
1271
+
1272
+ **Test Executions:**
1273
+ - ✅ Version-specific execution creation
1274
+ - ✅ Test data support
1275
+ - ✅ Individual step updates
1276
+ - ✅ Iteration and version management
1277
+ - ✅ List executions across all versions
1278
+
1279
+ **Test Cycles:**
1280
+ - ✅ Iteration management
1281
+ - ✅ Link deletion
1282
+
1283
+ **Test Plans:**
1284
+ - ✅ Link deletion
1285
+
1286
+ ### What Cannot Be Done
1287
+
1288
+ **Completely Unsupported:**
1289
+ - ❌ Delete test cases (only archive)
1290
+ - ❌ Delete test executions (immutable)
1291
+ - ❌ Delete test cycles (immutable)
1292
+ - ❌ Delete test plans (immutable)
1293
+ - ❌ Update test case metadata for older versions (only test script data)
1294
+ - ❌ Bulk operations (must iterate)
1295
+ - ❌ Transaction support (no rollback)
1296
+
1297
+ **Requires Workarounds:**
1298
+ - ❌ Update comments (delete and recreate)
1299
+ - ❌ Update attachments (delete and recreate)
1300
+ - ❌ Bulk updates (iterate and update individually)
1301
+
1302
+ ---
1303
+
1304
+ ## Best Practices
1305
+
1306
+ ### 1. Use Public API When Possible
1307
+
1308
+ Prefer public API methods over private API methods when functionality is available:
1309
+ - Public API is officially supported
1310
+ - Public API is more stable
1311
+ - Public API has better documentation
1312
+
1313
+ ### 2. Handle Errors Appropriately
1314
+
1315
+ ```typescript
1316
+ try {
1317
+ const testCase = await Zephyr.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
1318
+ } catch (error) {
1319
+ if (error instanceof NotFoundError) {
1320
+ // Handle not found
1321
+ } else if (error instanceof UnauthorizedError) {
1322
+ // Handle authentication failure
1323
+ } else {
1324
+ // Handle other errors
1325
+ }
1326
+ }
1327
+ ```
1328
+
1329
+ ### 3. Use Pagination Helpers
1330
+
1331
+ For large datasets, use cursor-based pagination when available:
1332
+ ```typescript
1333
+ // Better performance
1334
+ const testCases = await Zephyr.TestCase.listTestCasesCursorPaginated({
1335
+ projectKey: 'PROJ',
1336
+ limit: 100
1337
+ });
1338
+ ```
1339
+
1340
+ ### 4. Cache Context JWT Tokens
1341
+
1342
+ Private API methods automatically handle token caching, but if you're making many calls:
1343
+ - Tokens expire after 15 minutes
1344
+ - Methods automatically refresh tokens
1345
+ - No manual token management needed
1346
+
1347
+ ### 5. Use Version Support Wisely
1348
+
1349
+ When working with versions:
1350
+ - Always check available versions first
1351
+ - Use `listTestCaseVersions()` to find the latest version
1352
+ - Be aware that version numbers are absolute (1-based)
1353
+ - Latest version = highest version number
1354
+
1355
+ ### 6. Test Step Management
1356
+
1357
+ When updating test steps:
1358
+ - Use `getTestCaseTestStepsWithIds()` to get step IDs
1359
+ - Include step IDs when updating existing steps
1360
+ - Use 'APPEND' mode to add steps without losing existing ones
1361
+ - Use 'OVERWRITE' mode to replace all steps
1362
+
1363
+ ### 7. Error Strategy for Public API
1364
+
1365
+ Use error strategy for graceful error handling:
1366
+ ```typescript
1367
+ const testCase = await Zephyr.TestCase.getTestCase(
1368
+ { testCaseKey: 'PROJ-T1' },
1369
+ {
1370
+ handleHttp404Error: () => ({ type: 'return', value: null })
1371
+ }
1372
+ );
1373
+
1374
+ if (!testCase) {
1375
+ // Handle missing test case
1376
+ }
1377
+ ```
1378
+
1379
+ ### 8. Verbose Logging for Debugging
1380
+
1381
+ Enable verbose logging in production for better error diagnostics:
1382
+ ```typescript
1383
+ const Zephyr = createZephyrApi(ZephyrApiConnection, true);
1384
+ ```
1385
+
1386
+ ### 9. Type Safety
1387
+
1388
+ Always use TypeScript types:
1389
+ ```typescript
1390
+ import type { TestCase, TestExecution } from '@rbaileysr/zephyr-managed-api';
1391
+
1392
+ const testCase: TestCase = await Zephyr.TestCase.getTestCase({
1393
+ testCaseKey: 'PROJ-T1'
1394
+ });
1395
+ ```
1396
+
1397
+ ### 10. Private API Warnings
1398
+
1399
+ When using private API methods:
1400
+ - Document why private API is needed
1401
+ - Be prepared for breaking changes
1402
+ - Test thoroughly after Zephyr updates
1403
+ - Have fallback plans if methods break
1404
+
1405
+ ---
1406
+
1407
+ ## Summary
1408
+
1409
+ This Managed API provides comprehensive access to Zephyr Scale Cloud functionality through both public and private endpoints. Use public API methods when possible, and leverage private API methods for advanced functionality like version-specific operations, test data management, and extended data access.
1410
+
1411
+ **Key Takeaways:**
1412
+ - Public API = Officially supported, stable, well-documented
1413
+ - Private API = Advanced features, use with caution, may break
1414
+ - Version support = Many private API methods support version parameters
1415
+ - Error handling = Comprehensive error types with automatic retry
1416
+ - Pagination = Both offset and cursor-based options available
1417
+
1418
+ For detailed examples, see `examples.ts` in the package.
1419
+
1420
+ ---
1421
+
1422
+ **Copyright Adaptavist 2025 (c) All rights reserved**
1423
+