@rbaileysr/zephyr-managed-api 1.0.1 → 1.1.0
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.
- package/README.md +189 -1
- package/dist/README.md +865 -0
- package/dist/error-strategy.d.ts +3 -0
- package/dist/error-strategy.d.ts.map +1 -1
- package/dist/error-strategy.js +3 -0
- package/dist/groups/All.d.ts +3 -0
- package/dist/groups/All.d.ts.map +1 -1
- package/dist/groups/All.js +2 -6
- package/dist/groups/Automation.d.ts +3 -0
- package/dist/groups/Automation.d.ts.map +1 -1
- package/dist/groups/Automation.js +2 -3
- package/dist/groups/Environment.d.ts +3 -0
- package/dist/groups/Environment.d.ts.map +1 -1
- package/dist/groups/Environment.js +2 -3
- package/dist/groups/Folder.d.ts +3 -0
- package/dist/groups/Folder.d.ts.map +1 -1
- package/dist/groups/Folder.js +2 -3
- package/dist/groups/IssueLink.d.ts +3 -0
- package/dist/groups/IssueLink.d.ts.map +1 -1
- package/dist/groups/IssueLink.js +2 -3
- package/dist/groups/Link.d.ts +3 -0
- package/dist/groups/Link.d.ts.map +1 -1
- package/dist/groups/Link.js +2 -3
- package/dist/groups/Priority.d.ts +3 -0
- package/dist/groups/Priority.d.ts.map +1 -1
- package/dist/groups/Priority.js +2 -3
- package/dist/groups/Private.d.ts +89 -0
- package/dist/groups/Private.d.ts.map +1 -0
- package/dist/groups/Private.js +221 -0
- package/dist/groups/Project.d.ts +3 -0
- package/dist/groups/Project.d.ts.map +1 -1
- package/dist/groups/Project.js +2 -3
- package/dist/groups/Status.d.ts +3 -0
- package/dist/groups/Status.d.ts.map +1 -1
- package/dist/groups/Status.js +2 -3
- package/dist/groups/TestCase.d.ts +3 -0
- package/dist/groups/TestCase.d.ts.map +1 -1
- package/dist/groups/TestCase.js +2 -3
- package/dist/groups/TestCycle.d.ts +3 -0
- package/dist/groups/TestCycle.d.ts.map +1 -1
- package/dist/groups/TestCycle.js +2 -3
- package/dist/groups/TestExecution.d.ts +3 -0
- package/dist/groups/TestExecution.d.ts.map +1 -1
- package/dist/groups/TestExecution.js +2 -3
- package/dist/groups/TestPlan.d.ts +3 -0
- package/dist/groups/TestPlan.d.ts.map +1 -1
- package/dist/groups/TestPlan.js +2 -3
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/package.json +54 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -0
- package/dist/utils-api-call.d.ts +3 -0
- package/dist/utils-api-call.d.ts.map +1 -1
- package/dist/utils-api-call.js +3 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +3 -0
- package/package.json +4 -4
package/dist/README.md
ADDED
|
@@ -0,0 +1,865 @@
|
|
|
1
|
+
# Zephyr Managed API
|
|
2
|
+
|
|
3
|
+
A comprehensive Managed API wrapper for Zephyr Cloud REST API v2, providing type-safe, hierarchical access to all Zephyr API endpoints.
|
|
4
|
+
|
|
5
|
+
> **⚠️ Important: ScriptRunner Connect Runtime Only**
|
|
6
|
+
>
|
|
7
|
+
> This package is specifically designed for **ScriptRunner Connect's custom runtime** and will **NOT work in standard Node.js projects**. It uses web standards-based APIs (fetch, etc.) and ES modules, making it compatible with ScriptRunner Connect's runtime environment.
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
This Managed API wrapper provides a clean, type-safe interface to interact with the Zephyr Cloud API. It follows the same hierarchical pattern as other ScriptRunner Connect Managed APIs, making it easy to use and consistent with the platform's conventions.
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Type-Safe**: Full TypeScript support with IntelliSense
|
|
16
|
+
- **Hierarchical Structure**: Organized by resource type (TestCase, TestCycle, TestPlan, etc.)
|
|
17
|
+
- **Comprehensive Coverage**: Supports all Zephyr Cloud REST API v2 endpoints
|
|
18
|
+
- **Error Handling**: Built-in error parsing and handling using Commons Core error types
|
|
19
|
+
- **Pagination Support**: Both offset-based and cursor-based pagination
|
|
20
|
+
- **Flexible Authentication**: Supports OAuth tokens and ScriptRunner Connect API Connections (base URL configured in Generic Connector)
|
|
21
|
+
- **Custom Fields**: Full support for dynamic custom fields
|
|
22
|
+
- **Web App Compatible**: Works seamlessly in ScriptRunner Connect web app
|
|
23
|
+
- **Single Import**: Convenient default export for all utilities and types
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
### NPM Package
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm install @rbaileysr/zephyr-managed-api
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Important:** After installing via NPM, you must also add the package through ScriptRunner Connect's Package Manager in the web UI. The package will then be available in your workspace.
|
|
34
|
+
|
|
35
|
+
### ScriptRunner Connect Workspace Setup
|
|
36
|
+
|
|
37
|
+
1. **Add Package via Web UI:**
|
|
38
|
+
- Go to Package Manager in ScriptRunner Connect web UI
|
|
39
|
+
- Click "Add Package"
|
|
40
|
+
- Enter: `@rbaileysr/zephyr-managed-api`
|
|
41
|
+
- Click Add/Save
|
|
42
|
+
|
|
43
|
+
2. **Sync Workspace Files:**
|
|
44
|
+
- Download latest workspace files from SFTP server
|
|
45
|
+
- Or use `SFTP: Sync Remote → Local` if using VS Code + SFTP
|
|
46
|
+
|
|
47
|
+
3. **Install Dependencies:**
|
|
48
|
+
```bash
|
|
49
|
+
npm install
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
4. **Use in Scripts:**
|
|
53
|
+
```typescript
|
|
54
|
+
// Single import (recommended) - everything in one import
|
|
55
|
+
import Zephyr from '@rbaileysr/zephyr-managed-api';
|
|
56
|
+
import ZephyrApiConnection from '../api/zephyr';
|
|
57
|
+
|
|
58
|
+
// Using API Connection (recommended for ScriptRunner Connect)
|
|
59
|
+
// Base URL is configured in the Generic Connector
|
|
60
|
+
const api = Zephyr.createZephyrApi(ZephyrApiConnection);
|
|
61
|
+
|
|
62
|
+
// Access utilities and error types from the same import
|
|
63
|
+
const pages = await Zephyr.getAllPages(...);
|
|
64
|
+
const errorStrategy = new Zephyr.ErrorStrategyBuilder()...;
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Alternative - Named Imports:**
|
|
68
|
+
```typescript
|
|
69
|
+
// Named imports (if you prefer)
|
|
70
|
+
import { createZephyrApi, getAllPages, ErrorStrategyBuilder } from '@rbaileysr/zephyr-managed-api';
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Usage
|
|
74
|
+
|
|
75
|
+
### Basic Examples
|
|
76
|
+
|
|
77
|
+
#### Using API Connection (ScriptRunner Connect) - Single Import
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
// Single import for everything
|
|
81
|
+
import Zephyr from '@rbaileysr/zephyr-managed-api';
|
|
82
|
+
import ZephyrApiConnection from '../api/zephyr';
|
|
83
|
+
|
|
84
|
+
// Create API instance (base URL configured in Generic Connector)
|
|
85
|
+
const api = Zephyr.createZephyrApi(ZephyrApiConnection);
|
|
86
|
+
|
|
87
|
+
// Get a test case
|
|
88
|
+
const testCase = await api.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
|
|
89
|
+
console.log(`Test case: ${testCase.name}`);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### Using API Connection - Named Imports
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// Named imports (alternative)
|
|
96
|
+
import { createZephyrApi } from '@rbaileysr/zephyr-managed-api';
|
|
97
|
+
import ZephyrApiConnection from '../api/zephyr';
|
|
98
|
+
|
|
99
|
+
const api = createZephyrApi(ZephyrApiConnection);
|
|
100
|
+
const testCase = await api.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
#### Using OAuth Token
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
import Zephyr from '@rbaileysr/zephyr-managed-api';
|
|
107
|
+
|
|
108
|
+
// OAuth token with full base URL (US region)
|
|
109
|
+
const api = Zephyr.createZephyrApi(
|
|
110
|
+
'your-oauth-token-here',
|
|
111
|
+
'https://api.zephyrscale.smartbear.com/v2'
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
// OAuth token with full base URL (EU region)
|
|
115
|
+
const apiEU = Zephyr.createZephyrApi(
|
|
116
|
+
'your-oauth-token-here',
|
|
117
|
+
'https://eu.api.zephyrscale.smartbear.com/v2'
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
// List test cases
|
|
121
|
+
const testCases = await api.TestCase.listTestCases({
|
|
122
|
+
projectKey: 'PROJ',
|
|
123
|
+
maxResults: 10,
|
|
124
|
+
startAt: 0
|
|
125
|
+
});
|
|
126
|
+
console.log(`Found ${testCases.values.length} test cases`);
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### Create a Test Case
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
const testCase = await api.TestCase.createTestCase({
|
|
133
|
+
body: {
|
|
134
|
+
projectKey: 'PROJ',
|
|
135
|
+
name: 'Login Test Case',
|
|
136
|
+
objective: 'Verify user can login successfully',
|
|
137
|
+
precondition: 'User account exists',
|
|
138
|
+
priorityName: 'High',
|
|
139
|
+
statusName: 'Draft',
|
|
140
|
+
labels: ['automated', 'regression'],
|
|
141
|
+
customFields: {
|
|
142
|
+
'Build Number': '2024.1',
|
|
143
|
+
'Release Date': '2024-01-15'
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
console.log(`Created test case: ${testCase.key}`);
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
#### Create a Test Cycle
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
const testCycle = await api.TestCycle.createTestCycle({
|
|
154
|
+
body: {
|
|
155
|
+
projectKey: 'PROJ',
|
|
156
|
+
name: 'Sprint 1 Regression',
|
|
157
|
+
description: 'Regression tests for Sprint 1',
|
|
158
|
+
plannedStartDate: '2024-01-15T09:00:00Z',
|
|
159
|
+
plannedEndDate: '2024-01-22T17:00:00Z',
|
|
160
|
+
statusName: 'In Progress',
|
|
161
|
+
customFields: {
|
|
162
|
+
'Environment': 'Production'
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
console.log(`Created test cycle: ${testCycle.key}`);
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### Create a Test Execution
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
const testExecution = await api.TestExecution.createTestExecution({
|
|
173
|
+
body: {
|
|
174
|
+
projectKey: 'PROJ',
|
|
175
|
+
testCaseKey: 'PROJ-T1',
|
|
176
|
+
testCycleKey: 'PROJ-R1',
|
|
177
|
+
statusName: 'Pass',
|
|
178
|
+
environmentName: 'Chrome Latest',
|
|
179
|
+
executionTime: 120000, // 2 minutes in milliseconds
|
|
180
|
+
comment: 'Test passed successfully'
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
console.log(`Created test execution: ${testExecution.key || testExecution.id}`);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
#### Update a Test Case
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
// First, get the test case
|
|
190
|
+
const testCase = await api.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
|
|
191
|
+
|
|
192
|
+
// Update it
|
|
193
|
+
testCase.name = 'Updated Test Case Name';
|
|
194
|
+
testCase.objective = 'Updated objective';
|
|
195
|
+
testCase.labels = [...(testCase.labels || []), 'updated'];
|
|
196
|
+
|
|
197
|
+
await api.TestCase.updateTestCase({
|
|
198
|
+
testCaseKey: 'PROJ-T1',
|
|
199
|
+
body: testCase
|
|
200
|
+
});
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
#### List with Filters and Pagination
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
// Offset-based pagination
|
|
207
|
+
const testCases = await api.TestCase.listTestCases({
|
|
208
|
+
projectKey: 'PROJ',
|
|
209
|
+
folderId: 12345,
|
|
210
|
+
maxResults: 50,
|
|
211
|
+
startAt: 0
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
// Cursor-based pagination (for large datasets)
|
|
215
|
+
const testCasesCursor = await api.TestCase.listTestCasesCursorPaginated({
|
|
216
|
+
projectKey: 'PROJ',
|
|
217
|
+
limit: 100,
|
|
218
|
+
startAtId: 0
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
#### Create Links
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
// Link test case to Jira issue
|
|
226
|
+
const issueLink = await api.TestCase.createTestCaseIssueLink({
|
|
227
|
+
testCaseKey: 'PROJ-T1',
|
|
228
|
+
body: {
|
|
229
|
+
issueId: 12345
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Link test case to web URL
|
|
234
|
+
const webLink = await api.TestCase.createTestCaseWebLink({
|
|
235
|
+
testCaseKey: 'PROJ-T1',
|
|
236
|
+
body: {
|
|
237
|
+
url: 'https://example.com/test-resource',
|
|
238
|
+
description: 'External test resource'
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## API Groups
|
|
244
|
+
|
|
245
|
+
The Managed API is organized into the following groups:
|
|
246
|
+
|
|
247
|
+
### Project
|
|
248
|
+
- `listProjects(options?)` - List all projects
|
|
249
|
+
- `getProject(options)` - Get a specific project
|
|
250
|
+
|
|
251
|
+
### Status
|
|
252
|
+
- `listStatuses(options)` - List all statuses
|
|
253
|
+
- `getStatus(options)` - Get a specific status
|
|
254
|
+
- `createStatus(request)` - Create a new status
|
|
255
|
+
- `updateStatus(request)` - Update a status
|
|
256
|
+
|
|
257
|
+
### Priority
|
|
258
|
+
- `listPriorities(options)` - List all priorities
|
|
259
|
+
- `getPriority(options)` - Get a specific priority
|
|
260
|
+
- `createPriority(request)` - Create a new priority
|
|
261
|
+
- `updatePriority(request)` - Update a priority
|
|
262
|
+
|
|
263
|
+
### Environment
|
|
264
|
+
- `listEnvironments(options)` - List all environments
|
|
265
|
+
- `getEnvironment(options)` - Get a specific environment
|
|
266
|
+
- `createEnvironment(request)` - Create a new environment
|
|
267
|
+
- `updateEnvironment(request)` - Update an environment
|
|
268
|
+
|
|
269
|
+
### Folder
|
|
270
|
+
- `listFolders(options)` - List all folders
|
|
271
|
+
- `getFolder(options)` - Get a specific folder
|
|
272
|
+
- `createFolder(request)` - Create a new folder
|
|
273
|
+
|
|
274
|
+
### TestCase
|
|
275
|
+
- `listTestCases(options?)` - List all test cases
|
|
276
|
+
- `listTestCasesCursorPaginated(options?)` - List test cases with cursor pagination
|
|
277
|
+
- `getTestCase(options)` - Get a specific test case
|
|
278
|
+
- `createTestCase(request)` - Create a new test case
|
|
279
|
+
- `updateTestCase(request)` - Update a test case
|
|
280
|
+
- `getTestCaseLinks(testCaseKey)` - Get links for a test case
|
|
281
|
+
- `createTestCaseIssueLink(request)` - Create issue link
|
|
282
|
+
- `createTestCaseWebLink(request)` - Create web link
|
|
283
|
+
- `listTestCaseVersions(options)` - List test case versions
|
|
284
|
+
- `getTestCaseVersion(options)` - Get a specific version
|
|
285
|
+
- `getTestCaseTestScript(testCaseKey)` - Get test script
|
|
286
|
+
- `createTestCaseTestScript(request)` - Create or update test script
|
|
287
|
+
- `getTestCaseTestSteps(testCaseKey, options?)` - Get test steps
|
|
288
|
+
- `createTestCaseTestSteps(request)` - Create test steps
|
|
289
|
+
|
|
290
|
+
### TestCycle
|
|
291
|
+
- `listTestCycles(options?)` - List all test cycles
|
|
292
|
+
- `getTestCycle(options)` - Get a specific test cycle
|
|
293
|
+
- `createTestCycle(request)` - Create a new test cycle
|
|
294
|
+
- `updateTestCycle(request)` - Update a test cycle
|
|
295
|
+
- `getTestCycleLinks(testCycleIdOrKey)` - Get links for a test cycle
|
|
296
|
+
- `createTestCycleIssueLink(request)` - Create issue link
|
|
297
|
+
- `createTestCycleWebLink(request)` - Create web link
|
|
298
|
+
|
|
299
|
+
### TestPlan
|
|
300
|
+
- `listTestPlans(options?)` - List all test plans
|
|
301
|
+
- `getTestPlan(options)` - Get a specific test plan
|
|
302
|
+
- `createTestPlan(request)` - Create a new test plan
|
|
303
|
+
- `createTestPlanIssueLink(request)` - Create issue link
|
|
304
|
+
- `createTestPlanWebLink(request)` - Create web link
|
|
305
|
+
- `createTestPlanTestCycleLink(request)` - Link test cycle to test plan
|
|
306
|
+
|
|
307
|
+
### TestExecution
|
|
308
|
+
- `listTestExecutions(options?)` - List all test executions
|
|
309
|
+
- `listTestExecutionsNextgen(options?)` - List test executions with cursor pagination
|
|
310
|
+
- `getTestExecution(options)` - Get a specific test execution
|
|
311
|
+
- `createTestExecution(request)` - Create a new test execution
|
|
312
|
+
- `updateTestExecution(request)` - Update a test execution
|
|
313
|
+
- `getTestExecutionTestSteps(options)` - Get test steps for execution
|
|
314
|
+
- `putTestExecutionTestSteps(request)` - Update test steps
|
|
315
|
+
- `syncTestExecutionScript(request)` - Sync with test case script
|
|
316
|
+
- `listTestExecutionLinks(testExecutionIdOrKey)` - Get links
|
|
317
|
+
- `createTestExecutionIssueLink(request)` - Create issue link
|
|
318
|
+
|
|
319
|
+
### Link
|
|
320
|
+
- `deleteLink(options)` - Delete a link (idempotent)
|
|
321
|
+
|
|
322
|
+
### IssueLink
|
|
323
|
+
- `getIssueLinkTestCases(options)` - Get test cases linked to issue
|
|
324
|
+
- `getIssueLinkTestCycles(options)` - Get test cycles linked to issue
|
|
325
|
+
- `getIssueLinkTestPlans(options)` - Get test plans linked to issue
|
|
326
|
+
- `getIssueLinkExecutions(options)` - Get test executions linked to issue
|
|
327
|
+
|
|
328
|
+
### Automation
|
|
329
|
+
- `createCustomExecutions(request)` - Upload custom format results
|
|
330
|
+
- `createCucumberExecutions(request)` - Upload Cucumber results
|
|
331
|
+
- `createJUnitExecutions(request)` - Upload JUnit XML results
|
|
332
|
+
- `retrieveBDDTestCases(options)` - Retrieve BDD feature files
|
|
333
|
+
|
|
334
|
+
### Private API ⚠️
|
|
335
|
+
> **⚠️ WARNING: Private API Methods**
|
|
336
|
+
>
|
|
337
|
+
> The following methods use Zephyr's private/unofficial API endpoints that are:
|
|
338
|
+
> - **Not officially supported** by SmartBear
|
|
339
|
+
> - **Not part of the public API documentation**
|
|
340
|
+
> - **Subject to change at any time** without notice
|
|
341
|
+
> - **Not covered by Standard Support**
|
|
342
|
+
>
|
|
343
|
+
> Use these methods at your own risk. They may break with future Zephyr updates.
|
|
344
|
+
|
|
345
|
+
- `getContextJwt(userEmail, apiToken, jiraInstanceUrl)` - Get Jira Context JWT token (required for private API calls)
|
|
346
|
+
- `createCustomField(userEmail, apiToken, jiraInstanceUrl, category, request)` - Create custom fields for test cases, test plans, test runs, or test steps
|
|
347
|
+
- `createTestCaseVersion(userEmail, apiToken, jiraInstanceUrl, testCaseId, projectId)` - Create a new test case version
|
|
348
|
+
|
|
349
|
+
## Authentication
|
|
350
|
+
|
|
351
|
+
### Using ScriptRunner Connect API Connection (Recommended)
|
|
352
|
+
|
|
353
|
+
When using in ScriptRunner Connect, configure a Generic Connector with the full base URL in the web UI:
|
|
354
|
+
|
|
355
|
+
**For US region:** `https://api.zephyrscale.smartbear.com/v2`
|
|
356
|
+
**For EU region:** `https://eu.api.zephyrscale.smartbear.com/v2`
|
|
357
|
+
|
|
358
|
+
Then use it in your script:
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
import Zephyr from '@rbaileysr/zephyr-managed-api';
|
|
362
|
+
import ZephyrApiConnection from '../api/zephyr';
|
|
363
|
+
|
|
364
|
+
// Base URL is configured in the Generic Connector
|
|
365
|
+
const api = Zephyr.createZephyrApi(ZephyrApiConnection);
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Using OAuth Token
|
|
369
|
+
|
|
370
|
+
For local testing or when using OAuth tokens directly, provide the full base URL:
|
|
371
|
+
|
|
372
|
+
```typescript
|
|
373
|
+
import Zephyr from '@rbaileysr/zephyr-managed-api';
|
|
374
|
+
|
|
375
|
+
// US region
|
|
376
|
+
const api = Zephyr.createZephyrApi(
|
|
377
|
+
'your-oauth-token',
|
|
378
|
+
'https://api.zephyrscale.smartbear.com/v2'
|
|
379
|
+
);
|
|
380
|
+
|
|
381
|
+
// EU region
|
|
382
|
+
const apiEU = Zephyr.createZephyrApi(
|
|
383
|
+
'your-oauth-token',
|
|
384
|
+
'https://eu.api.zephyrscale.smartbear.com/v2'
|
|
385
|
+
);
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
## Private API ⚠️
|
|
389
|
+
|
|
390
|
+
> **⚠️ WARNING: Private API Usage**
|
|
391
|
+
>
|
|
392
|
+
> The Private API methods use Zephyr's private/unofficial endpoints that are not officially supported by SmartBear. These endpoints may change or be removed at any time without notice and are not covered by Standard Support. Use these methods at your own risk.
|
|
393
|
+
|
|
394
|
+
The Private API group provides access to functionality not available in the public Zephyr API, such as creating custom fields and test case versions. These methods require Jira user credentials (email and API token) rather than OAuth tokens.
|
|
395
|
+
|
|
396
|
+
### Authentication
|
|
397
|
+
|
|
398
|
+
Private API methods use Jira Basic Authentication (email + API token) to retrieve a Context JWT token, which is then used to authenticate with Zephyr's private endpoints.
|
|
399
|
+
|
|
400
|
+
### Get Context JWT
|
|
401
|
+
|
|
402
|
+
The Context JWT is a short-lived token (15 minutes) required for all private API calls:
|
|
403
|
+
|
|
404
|
+
```typescript
|
|
405
|
+
import Zephyr from '@rbaileysr/zephyr-managed-api';
|
|
406
|
+
import ZephyrApiConnection from '../api/zephyr';
|
|
407
|
+
|
|
408
|
+
const api = Zephyr.createZephyrApi(ZephyrApiConnection);
|
|
409
|
+
|
|
410
|
+
// Get Context JWT token
|
|
411
|
+
const contextJwt = await api.Private.getContextJwt(
|
|
412
|
+
'user@example.com',
|
|
413
|
+
'jira-api-token',
|
|
414
|
+
'https://your-instance.atlassian.net'
|
|
415
|
+
);
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
### Create Custom Fields
|
|
419
|
+
|
|
420
|
+
Create custom fields for test cases, test plans, test runs, or test steps:
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
// Create a basic custom field for test cases
|
|
424
|
+
const customField = await api.Private.createCustomField(
|
|
425
|
+
'user@example.com',
|
|
426
|
+
'jira-api-token',
|
|
427
|
+
'https://your-instance.atlassian.net',
|
|
428
|
+
'TEST_CASE', // Category: TEST_CASE, TEST_PLAN, TEST_RUN, or TEST_STEP
|
|
429
|
+
{
|
|
430
|
+
projectId: 10017,
|
|
431
|
+
name: 'Build Number',
|
|
432
|
+
type: 'SINGLE_LINE_TEXT', // CHECKBOX, NUMBER, DECIMAL, SINGLE_LINE_TEXT, MULTI_LINE_TEXT, SINGLE_CHOICE_SELECT_LIST, MULTI_CHOICE_SELECT_LIST, USER_LIST, DATE
|
|
433
|
+
required: false,
|
|
434
|
+
index: 4,
|
|
435
|
+
category: 'TEST_CASE',
|
|
436
|
+
options: [], // Only for SINGLE_CHOICE_SELECT_LIST or MULTI_CHOICE_SELECT_LIST
|
|
437
|
+
archived: false
|
|
438
|
+
}
|
|
439
|
+
);
|
|
440
|
+
|
|
441
|
+
// Create a custom field with options (select list)
|
|
442
|
+
const selectField = await api.Private.createCustomField(
|
|
443
|
+
'user@example.com',
|
|
444
|
+
'jira-api-token',
|
|
445
|
+
'https://your-instance.atlassian.net',
|
|
446
|
+
'TEST_CASE',
|
|
447
|
+
{
|
|
448
|
+
projectId: 10017,
|
|
449
|
+
name: 'Test Category',
|
|
450
|
+
type: 'MULTI_CHOICE_SELECT_LIST',
|
|
451
|
+
required: false,
|
|
452
|
+
index: 5,
|
|
453
|
+
category: 'TEST_CASE',
|
|
454
|
+
options: [
|
|
455
|
+
{ index: 1, name: 'Smoke', archived: false },
|
|
456
|
+
{ index: 2, name: 'Regression', archived: false },
|
|
457
|
+
{ index: 3, name: 'Performance', archived: false }
|
|
458
|
+
],
|
|
459
|
+
archived: false
|
|
460
|
+
}
|
|
461
|
+
);
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
**Available Custom Field Types:**
|
|
465
|
+
- `CHECKBOX` - Checkbox
|
|
466
|
+
- `NUMBER` - Number
|
|
467
|
+
- `DECIMAL` - Decimal number
|
|
468
|
+
- `SINGLE_LINE_TEXT` - Single-line text
|
|
469
|
+
- `MULTI_LINE_TEXT` - Multi-line text
|
|
470
|
+
- `SINGLE_CHOICE_SELECT_LIST` - Single-choice select list
|
|
471
|
+
- `MULTI_CHOICE_SELECT_LIST` - Multi-choice select list
|
|
472
|
+
- `USER_LIST` - User picker
|
|
473
|
+
- `DATE` - Date picker
|
|
474
|
+
|
|
475
|
+
**Available Categories:**
|
|
476
|
+
- `TEST_CASE` - Custom field for test cases
|
|
477
|
+
- `TEST_PLAN` - Custom field for test plans
|
|
478
|
+
- `TEST_RUN` - Custom field for test cycles (test runs)
|
|
479
|
+
- `TEST_STEP` - Custom field for test steps
|
|
480
|
+
|
|
481
|
+
### Create Test Case Version
|
|
482
|
+
|
|
483
|
+
Create a new version of an existing test case. **Note:** When a new version is created, the `testCaseId` changes for that test case.
|
|
484
|
+
|
|
485
|
+
```typescript
|
|
486
|
+
// First, get the test case to find its numeric ID
|
|
487
|
+
const testCase = await api.TestCase.getTestCase({ testCaseKey: 'PROJ-T1' });
|
|
488
|
+
const testCaseId = testCase.id; // Numeric ID, not the key
|
|
489
|
+
|
|
490
|
+
// Create a new version
|
|
491
|
+
const newVersion = await api.Private.createTestCaseVersion(
|
|
492
|
+
'user@example.com',
|
|
493
|
+
'jira-api-token',
|
|
494
|
+
'https://your-instance.atlassian.net',
|
|
495
|
+
testCaseId, // Numeric test case ID
|
|
496
|
+
10017 // Project ID or key
|
|
497
|
+
);
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
**Important Notes:**
|
|
501
|
+
- The `testCaseId` must be the numeric ID, not the test case key (e.g., `PROJ-T1`)
|
|
502
|
+
- Use `api.TestCase.getTestCase()` to get the numeric ID from a test case key
|
|
503
|
+
- If a new version already exists, the API will return a 409 Conflict error
|
|
504
|
+
- The test case ID changes after creating a new version
|
|
505
|
+
|
|
506
|
+
### Error Handling for Private API
|
|
507
|
+
|
|
508
|
+
Private API methods use the same error types as the public API:
|
|
509
|
+
|
|
510
|
+
```typescript
|
|
511
|
+
try {
|
|
512
|
+
await api.Private.createCustomField(...);
|
|
513
|
+
} catch (error) {
|
|
514
|
+
if (error instanceof Zephyr.BadRequestError) {
|
|
515
|
+
console.log('Invalid request parameters');
|
|
516
|
+
} else if (error instanceof Zephyr.UnauthorizedError) {
|
|
517
|
+
console.log('Authentication failed - check your credentials');
|
|
518
|
+
} else if (error instanceof Zephyr.ForbiddenError) {
|
|
519
|
+
console.log('Insufficient permissions');
|
|
520
|
+
} else if (error instanceof Zephyr.NotFoundError) {
|
|
521
|
+
console.log('Resource not found');
|
|
522
|
+
} else if (error instanceof Zephyr.ServerError) {
|
|
523
|
+
if (error.status === 409) {
|
|
524
|
+
console.log('Conflict - version already exists');
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
## Custom Fields
|
|
531
|
+
|
|
532
|
+
Custom fields are supported as flexible key-value pairs:
|
|
533
|
+
|
|
534
|
+
```typescript
|
|
535
|
+
const customFields = {
|
|
536
|
+
'Build Number': 20,
|
|
537
|
+
'Release Date': '2024-01-15',
|
|
538
|
+
'Pre-Condition(s)': 'User should have logged in.<br>User should have navigated to the panel.',
|
|
539
|
+
'Implemented': false,
|
|
540
|
+
'Category': ['Performance', 'Regression'],
|
|
541
|
+
'Tester': 'user-account-id-here'
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
await api.TestCase.createTestCase({
|
|
545
|
+
body: {
|
|
546
|
+
projectKey: 'PROJ',
|
|
547
|
+
name: 'Test Case',
|
|
548
|
+
customFields: customFields
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
**Note**:
|
|
554
|
+
- Multi-line text fields support HTML with `<br>` tags
|
|
555
|
+
- Dates should be in format `yyyy-MM-dd`
|
|
556
|
+
- Users should have values of Jira User Account IDs
|
|
557
|
+
- Custom field types are defined in your Zephyr project configuration
|
|
558
|
+
|
|
559
|
+
## Error Handling
|
|
560
|
+
|
|
561
|
+
The API uses Commons Core-compatible error types for consistent error handling. All API methods automatically retry on rate limiting (HTTP 429) with exponential backoff.
|
|
562
|
+
|
|
563
|
+
### Error Types
|
|
564
|
+
|
|
565
|
+
```typescript
|
|
566
|
+
// Single import for everything
|
|
567
|
+
import Zephyr from '@rbaileysr/zephyr-managed-api';
|
|
568
|
+
import ZephyrApiConnection from '../api/zephyr';
|
|
569
|
+
|
|
570
|
+
const api = Zephyr.createZephyrApi(ZephyrApiConnection);
|
|
571
|
+
|
|
572
|
+
try {
|
|
573
|
+
const testCase = await api.TestCase.getTestCase({ testCaseKey: 'INVALID-T1' });
|
|
574
|
+
} catch (error) {
|
|
575
|
+
if (error instanceof Zephyr.NotFoundError) {
|
|
576
|
+
console.log('Test case not found');
|
|
577
|
+
} else if (error instanceof Zephyr.BadRequestError) {
|
|
578
|
+
console.log('Invalid request');
|
|
579
|
+
} else if (error instanceof Zephyr.TooManyRequestsError) {
|
|
580
|
+
console.log('Rate limited - this should have been retried automatically');
|
|
581
|
+
} else if (error instanceof Zephyr.HttpError) {
|
|
582
|
+
console.log(`HTTP error: ${error.message}`);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
```
|
|
586
|
+
|
|
587
|
+
**Alternative - Named Imports:**
|
|
588
|
+
```typescript
|
|
589
|
+
import {
|
|
590
|
+
createZephyrApi,
|
|
591
|
+
BadRequestError,
|
|
592
|
+
UnauthorizedError,
|
|
593
|
+
ForbiddenError,
|
|
594
|
+
NotFoundError,
|
|
595
|
+
TooManyRequestsError,
|
|
596
|
+
ServerError,
|
|
597
|
+
HttpError,
|
|
598
|
+
UnexpectedError
|
|
599
|
+
} from '@rbaileysr/zephyr-managed-api';
|
|
600
|
+
|
|
601
|
+
// Use named imports as before
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
### Automatic Rate Limiting Handling
|
|
605
|
+
|
|
606
|
+
All API methods automatically handle rate limiting (HTTP 429) with:
|
|
607
|
+
|
|
608
|
+
- **Exponential Backoff**: Starts at 1 second, doubles with each retry
|
|
609
|
+
- **Retry-After Header Support**: Respects `Retry-After` header when present
|
|
610
|
+
- **Configurable Retries**: Defaults to 5 retries, max delay of 60 seconds
|
|
611
|
+
- **Transparent Operation**: Retries happen automatically - no code changes needed
|
|
612
|
+
|
|
613
|
+
**Default Retry Configuration:**
|
|
614
|
+
- Maximum retries: 5
|
|
615
|
+
- Initial delay: 1 second
|
|
616
|
+
- Maximum delay: 60 seconds
|
|
617
|
+
- Backoff multiplier: 2x
|
|
618
|
+
|
|
619
|
+
**Example:**
|
|
620
|
+
```typescript
|
|
621
|
+
// This call will automatically retry on 429 errors
|
|
622
|
+
// You don't need to handle rate limiting manually
|
|
623
|
+
const testCases = await api.TestCase.listTestCases({ projectKey: 'PROJ' });
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
If rate limiting occurs:
|
|
627
|
+
1. The API waits (using Retry-After header if present, otherwise exponential backoff)
|
|
628
|
+
2. Retries the request automatically
|
|
629
|
+
3. Repeats up to 5 times
|
|
630
|
+
4. Only throws `TooManyRequestsError` if all retries are exhausted
|
|
631
|
+
|
|
632
|
+
### Error Strategy Support
|
|
633
|
+
|
|
634
|
+
For advanced error handling, you can provide an `errorStrategy` parameter to customize how errors are handled:
|
|
635
|
+
|
|
636
|
+
```typescript
|
|
637
|
+
import Zephyr from '@rbaileysr/zephyr-managed-api';
|
|
638
|
+
import ZephyrApiConnection from '../api/zephyr';
|
|
639
|
+
|
|
640
|
+
const api = Zephyr.createZephyrApi(ZephyrApiConnection);
|
|
641
|
+
|
|
642
|
+
// Return null instead of throwing on 404
|
|
643
|
+
const testCase = await api.TestCase.getTestCase(
|
|
644
|
+
{ testCaseKey: 'PROJ-T1' },
|
|
645
|
+
{
|
|
646
|
+
handleHttp404Error: () => ({ type: 'return', value: null })
|
|
647
|
+
}
|
|
648
|
+
);
|
|
649
|
+
|
|
650
|
+
// Using ErrorStrategyBuilder for cleaner syntax
|
|
651
|
+
const errorStrategy = new Zephyr.ErrorStrategyBuilder<TestCase | null>()
|
|
652
|
+
.http404Error(() => ({ type: 'return', value: null }))
|
|
653
|
+
.retryOnRateLimiting(10) // Retry up to 10 times on rate limiting
|
|
654
|
+
.http500Error(() => Zephyr.retry(5000)) // Retry server errors with 5s delay
|
|
655
|
+
.build();
|
|
656
|
+
|
|
657
|
+
const testCase2 = await api.TestCase.getTestCase(
|
|
658
|
+
{ testCaseKey: 'PROJ-T2' },
|
|
659
|
+
errorStrategy
|
|
660
|
+
);
|
|
661
|
+
```
|
|
662
|
+
|
|
663
|
+
**Available Error Strategy Handlers:**
|
|
664
|
+
- `handleHttp400Error` - Handle 400 Bad Request
|
|
665
|
+
- `handleHttp401Error` - Handle 401 Unauthorized
|
|
666
|
+
- `handleHttp403Error` - Handle 403 Forbidden
|
|
667
|
+
- `handleHttp404Error` - Handle 404 Not Found
|
|
668
|
+
- `handleHttp429Error` - Handle 429 Too Many Requests (receives retryCount)
|
|
669
|
+
- `handleHttp500Error` - Handle 500+ Server Errors
|
|
670
|
+
- `handleHttpError` - Handle any HTTP error (fallback)
|
|
671
|
+
|
|
672
|
+
**Error Strategy Actions:**
|
|
673
|
+
- `retry(delay)` - Retry the request after the specified delay (milliseconds)
|
|
674
|
+
- `continuePropagation()` - Let the error propagate normally (default)
|
|
675
|
+
- `{ type: 'return', value: T }` - Return a specific value instead of throwing
|
|
676
|
+
|
|
677
|
+
### Error Type Reference
|
|
678
|
+
|
|
679
|
+
| Error Type | HTTP Status | Description |
|
|
680
|
+
|------------|-------------|-------------|
|
|
681
|
+
| `BadRequestError` | 400 | Invalid request parameters |
|
|
682
|
+
| `UnauthorizedError` | 401 | Authentication required or invalid |
|
|
683
|
+
| `ForbiddenError` | 403 | Insufficient permissions |
|
|
684
|
+
| `NotFoundError` | 404 | Resource not found |
|
|
685
|
+
| `TooManyRequestsError` | 429 | Rate limit exceeded (after retries) |
|
|
686
|
+
| `ServerError` | 500+ | Server-side error |
|
|
687
|
+
| `HttpError` | Other | Generic HTTP error |
|
|
688
|
+
| `UnexpectedError` | N/A | Network or parsing errors |
|
|
689
|
+
|
|
690
|
+
## Pagination
|
|
691
|
+
|
|
692
|
+
### Manual Pagination
|
|
693
|
+
|
|
694
|
+
#### Offset-Based Pagination
|
|
695
|
+
|
|
696
|
+
```typescript
|
|
697
|
+
const testCases = await api.TestCase.listTestCases({
|
|
698
|
+
projectKey: 'PROJ',
|
|
699
|
+
maxResults: 50,
|
|
700
|
+
startAt: 0
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
// Check if more results available
|
|
704
|
+
if (!testCases.isLast) {
|
|
705
|
+
const nextPage = await api.TestCase.listTestCases({
|
|
706
|
+
projectKey: 'PROJ',
|
|
707
|
+
maxResults: 50,
|
|
708
|
+
startAt: testCases.startAt + testCases.maxResults
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
#### Cursor-Based Pagination
|
|
714
|
+
|
|
715
|
+
```typescript
|
|
716
|
+
const testCases = await api.TestCase.listTestCasesCursorPaginated({
|
|
717
|
+
projectKey: 'PROJ',
|
|
718
|
+
limit: 100,
|
|
719
|
+
startAtId: 0
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
// Get next page
|
|
723
|
+
if (testCases.nextStartAtId !== null) {
|
|
724
|
+
const nextPage = await api.TestCase.listTestCasesCursorPaginated({
|
|
725
|
+
projectKey: 'PROJ',
|
|
726
|
+
limit: 100,
|
|
727
|
+
startAtId: testCases.nextStartAtId
|
|
728
|
+
});
|
|
729
|
+
}
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
### Automatic Pagination with `getAllPages()`
|
|
733
|
+
|
|
734
|
+
For convenience, use `getAllPages()` to automatically fetch all pages:
|
|
735
|
+
|
|
736
|
+
#### Offset-Based Pagination
|
|
737
|
+
|
|
738
|
+
```typescript
|
|
739
|
+
import Zephyr from '@rbaileysr/zephyr-managed-api';
|
|
740
|
+
import ZephyrApiConnection from '../api/zephyr';
|
|
741
|
+
|
|
742
|
+
const api = Zephyr.createZephyrApi(ZephyrApiConnection);
|
|
743
|
+
|
|
744
|
+
// Automatically fetches all pages
|
|
745
|
+
const allTestCases = await Zephyr.getAllPages(
|
|
746
|
+
(startAt, maxResults) => api.TestCase.listTestCases({
|
|
747
|
+
projectKey: 'PROJ',
|
|
748
|
+
startAt,
|
|
749
|
+
maxResults
|
|
750
|
+
}),
|
|
751
|
+
{ maxResults: 50 } // Optional: page size
|
|
752
|
+
);
|
|
753
|
+
|
|
754
|
+
// allTestCases is an array of all TestCase objects from all pages
|
|
755
|
+
console.log(`Found ${allTestCases.length} test cases`);
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
#### Cursor-Based Pagination
|
|
759
|
+
|
|
760
|
+
```typescript
|
|
761
|
+
import Zephyr from '@rbaileysr/zephyr-managed-api';
|
|
762
|
+
import ZephyrApiConnection from '../api/zephyr';
|
|
763
|
+
|
|
764
|
+
const api = Zephyr.createZephyrApi(ZephyrApiConnection);
|
|
765
|
+
|
|
766
|
+
// Automatically fetches all pages
|
|
767
|
+
const allTestCases = await Zephyr.getAllPagesCursor(
|
|
768
|
+
(startAtId, limit) => api.TestCase.listTestCasesCursorPaginated({
|
|
769
|
+
projectKey: 'PROJ',
|
|
770
|
+
startAtId,
|
|
771
|
+
limit
|
|
772
|
+
}),
|
|
773
|
+
{ limit: 100 } // Optional: page size
|
|
774
|
+
);
|
|
775
|
+
|
|
776
|
+
// allTestCases is an array of all TestCase objects from all pages
|
|
777
|
+
console.log(`Found ${allTestCases.length} test cases`);
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
**Note**: `getAllPages()` and `getAllPagesCursor()` automatically handle pagination and will make multiple API calls as needed. Be mindful of rate limits when fetching large datasets.
|
|
781
|
+
|
|
782
|
+
## API Documentation
|
|
783
|
+
|
|
784
|
+
All API methods include comprehensive JSDoc comments with:
|
|
785
|
+
- Detailed descriptions of what each endpoint does
|
|
786
|
+
- Parameter documentation with types and requirements
|
|
787
|
+
- Return type documentation
|
|
788
|
+
- Links to official Zephyr API documentation
|
|
789
|
+
|
|
790
|
+
When using the package in ScriptRunner Connect, IntelliSense will display these descriptions and links in the code editor.
|
|
791
|
+
|
|
792
|
+
## Type Definitions
|
|
793
|
+
|
|
794
|
+
All TypeScript types are exported from the main module:
|
|
795
|
+
|
|
796
|
+
```typescript
|
|
797
|
+
import type {
|
|
798
|
+
TestCase,
|
|
799
|
+
TestCycle,
|
|
800
|
+
TestExecution,
|
|
801
|
+
TestPlan,
|
|
802
|
+
CustomFields,
|
|
803
|
+
ZephyrApiConnection,
|
|
804
|
+
ErrorStrategy,
|
|
805
|
+
ErrorStrategyBuilder
|
|
806
|
+
} from '@rbaileysr/zephyr-managed-api';
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
## All Group
|
|
810
|
+
|
|
811
|
+
For programmatic access to all methods, use the `All` group:
|
|
812
|
+
|
|
813
|
+
```typescript
|
|
814
|
+
// Access all methods through the All group
|
|
815
|
+
const testCase = await Zephyr.All.getTestCase({ testCaseKey: 'PROJ-T1' });
|
|
816
|
+
const testCycle = await Zephyr.All.createTestCycle({ body: { ... } });
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
The `All` group provides a single point of access to all API methods across all resource groups, useful for dynamic method invocation or when you need to iterate over all available methods.
|
|
820
|
+
|
|
821
|
+
## License
|
|
822
|
+
|
|
823
|
+
UNLICENSED - Copyright Adaptavist 2025 (c) All rights reserved
|
|
824
|
+
|
|
825
|
+
## Support
|
|
826
|
+
|
|
827
|
+
For issues, questions, or contributions, please refer to the project repository on GitHub.
|
|
828
|
+
|
|
829
|
+
## Links
|
|
830
|
+
|
|
831
|
+
- **NPM Package**: https://www.npmjs.com/package/@rbaileysr/zephyr-managed-api
|
|
832
|
+
- **Zephyr API Documentation**: https://support.smartbear.com/zephyr-scale-cloud/api-docs/v2/
|
|
833
|
+
- **ScriptRunner Connect Documentation**: https://docs.adaptavist.com/src/latest/
|
|
834
|
+
|
|
835
|
+
## Changelog
|
|
836
|
+
|
|
837
|
+
### 1.1.0
|
|
838
|
+
|
|
839
|
+
- **Added**: Private API group with support for unofficial Zephyr endpoints
|
|
840
|
+
- `getContextJwt()` - Retrieve Jira Context JWT token for private API authentication
|
|
841
|
+
- `createCustomField()` - Create custom fields for test cases, test plans, test runs, and test steps
|
|
842
|
+
- `createTestCaseVersion()` - Create new test case versions
|
|
843
|
+
- **Added**: Type definitions for private API requests (`CreatePrivateCustomFieldRequest`, `PrivateCustomFieldType`, `PrivateCustomFieldCategory`, etc.)
|
|
844
|
+
- **Warning**: Private API methods are not officially supported and may change without notice
|
|
845
|
+
|
|
846
|
+
### 1.0.1
|
|
847
|
+
|
|
848
|
+
- **Added**: Comprehensive JSDoc comments with API endpoint descriptions and links to official documentation
|
|
849
|
+
- **Added**: Single import option via default export for convenient usage
|
|
850
|
+
- **Changed**: Removed `region` parameter from `createZephyrApi` - base URL now configured in Generic Connector
|
|
851
|
+
- **Improved**: Error handling to support both `BadRequestError` and `NotFoundError` in test examples
|
|
852
|
+
- **Improved**: Type safety and IntelliSense support throughout the API
|
|
853
|
+
|
|
854
|
+
### 1.0.0
|
|
855
|
+
|
|
856
|
+
- **Initial Release**: Complete Managed API wrapper for Zephyr Cloud REST API v2
|
|
857
|
+
- **Added**: Full support for all Zephyr API endpoints (Test Cases, Test Cycles, Test Plans, Test Executions, etc.)
|
|
858
|
+
- **Added**: Type-safe TypeScript definitions for all API operations
|
|
859
|
+
- **Added**: Hierarchical API structure matching ScriptRunner Connect conventions
|
|
860
|
+
- **Added**: Automatic rate limiting retry with exponential backoff
|
|
861
|
+
- **Added**: Support for both API Connection and OAuth token authentication
|
|
862
|
+
- **Added**: Pagination helpers (`getAllPages`, `getAllPagesCursor`)
|
|
863
|
+
- **Added**: Error strategy builder for advanced error handling
|
|
864
|
+
- **Added**: Comprehensive error types compatible with Commons Core
|
|
865
|
+
|