@smartbear/mcp 0.23.0 → 0.25.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 +10 -2
- package/dist/bearq/client.js +12 -13
- package/dist/bearq/tool/tasks/chat-with-qa-lead.js +1 -0
- package/dist/bearq/tool/tasks/expand-application-model.js +1 -0
- package/dist/bearq/tool/tasks/get-task-status.js +1 -0
- package/dist/bearq/tool/tasks/get-task.js +1 -0
- package/dist/bearq/tool/tasks/refine-all-draft-tests.js +1 -0
- package/dist/bearq/tool/tasks/refine-test-cases.js +1 -0
- package/dist/bearq/tool/tasks/refine-tests-in-functional-areas.js +1 -0
- package/dist/bearq/tool/tasks/run-regression-tests.js +1 -0
- package/dist/bearq/tool/tasks/run-test-cases.js +1 -0
- package/dist/bearq/tool/tasks/run-tests-in-functional-areas.js +1 -0
- package/dist/bearq/tool/tasks/stop-task.js +1 -0
- package/dist/bearq/tool/tasks/wait-for-task.js +1 -0
- package/dist/bugsnag/client.js +24 -44
- package/dist/bugsnag/tool/error/get-error.js +1 -0
- package/dist/bugsnag/tool/error/list-project-errors.js +1 -0
- package/dist/bugsnag/tool/error/update-error.js +1 -0
- package/dist/bugsnag/tool/event/get-event-details-from-dashboard-url.js +1 -0
- package/dist/bugsnag/tool/event/get-event.js +1 -0
- package/dist/bugsnag/tool/event/list-error-events.js +1 -0
- package/dist/bugsnag/tool/performance/get-network-endpoint-groupings.js +1 -0
- package/dist/bugsnag/tool/performance/get-span-group.js +1 -0
- package/dist/bugsnag/tool/performance/get-trace.js +1 -0
- package/dist/bugsnag/tool/performance/list-span-groups.js +1 -0
- package/dist/bugsnag/tool/performance/list-spans.js +1 -0
- package/dist/bugsnag/tool/performance/list-trace-fields.js +1 -0
- package/dist/bugsnag/tool/performance/set-network-endpoint-groupings.js +1 -0
- package/dist/bugsnag/tool/project/get-current-project.js +1 -0
- package/dist/bugsnag/tool/project/list-project-event-filters.js +1 -0
- package/dist/bugsnag/tool/project/list-projects.js +1 -0
- package/dist/bugsnag/tool/release/get-build.js +1 -0
- package/dist/bugsnag/tool/release/get-release.js +1 -0
- package/dist/bugsnag/tool/release/list-releases.js +1 -0
- package/dist/collaborator/client.js +24 -19
- package/dist/common/client-registry.js +63 -29
- package/dist/common/server.js +57 -1
- package/dist/common/transport-http.js +90 -69
- package/dist/common/transport-stdio.js +29 -24
- package/dist/package.json.js +1 -1
- package/dist/pactflow/client/base.js +3 -3
- package/dist/pactflow/client/tools.js +102 -0
- package/dist/pactflow/client.js +30 -43
- package/dist/qmetry/client/tools/automation-tools.js +2 -0
- package/dist/qmetry/client/tools/issue-tools.js +6 -0
- package/dist/qmetry/client/tools/project-tools.js +9 -0
- package/dist/qmetry/client/tools/requirement-tools.js +5 -0
- package/dist/qmetry/client/tools/testcase-tools.js +7 -0
- package/dist/qmetry/client/tools/testsuite-tools.js +11 -0
- package/dist/qmetry/client.js +20 -18
- package/dist/qtm4j/client.js +57 -23
- package/dist/qtm4j/config/constants.js +197 -5
- package/dist/qtm4j/config/field-resolution.types.js +5 -2
- package/dist/qtm4j/http/api-client.js +90 -3
- package/dist/qtm4j/resolver/cache/cache.js +1 -1
- package/dist/qtm4j/resolver/resolver-registry.js +7 -1
- package/dist/qtm4j/resolver/resolvers/common-attribute-resolver.js +1 -0
- package/dist/qtm4j/resolver/resolvers/component-resolver.js +2 -0
- package/dist/qtm4j/resolver/resolvers/label-resolver.js +2 -0
- package/dist/qtm4j/resolver/resolvers/requirement-id-resolver.js +28 -0
- package/dist/qtm4j/resolver/resolvers/test-cycle-uid-resolver.js +28 -0
- package/dist/qtm4j/schema/automation.schema.js +107 -0
- package/dist/qtm4j/schema/linked-items.schema.js +95 -0
- package/dist/qtm4j/schema/requirements.schema.js +109 -0
- package/dist/qtm4j/schema/search-test-cycle.schema.js +133 -0
- package/dist/qtm4j/schema/test-cycle.link.schema.js +260 -0
- package/dist/qtm4j/schema/test-cycle.schema.js +39 -0
- package/dist/qtm4j/schema/update-test-cycle.schema.js +54 -0
- package/dist/qtm4j/tool/project/get-projects.js +2 -1
- package/dist/qtm4j/tool/project/set-project-context.js +2 -1
- package/dist/qtm4j/tool/requirement/get-linked-testcases.js +93 -0
- package/dist/qtm4j/tool/requirement/link-testcases.js +107 -0
- package/dist/qtm4j/tool/requirement/unlink-testcases.js +97 -0
- package/dist/qtm4j/tool/test-automation/get-automation-history.js +70 -0
- package/dist/qtm4j/tool/test-automation/upload-automation-result.js +144 -0
- package/dist/qtm4j/tool/test-case/create-test-case.js +2 -1
- package/dist/qtm4j/tool/test-case/get-linked-requirements.js +67 -0
- package/dist/qtm4j/tool/test-case/get-test-cases.js +2 -1
- package/dist/qtm4j/tool/test-case/get-test-steps.js +2 -1
- package/dist/qtm4j/tool/test-case/link-requirements.js +124 -0
- package/dist/qtm4j/tool/test-case/unlink-requirements.js +116 -0
- package/dist/qtm4j/tool/test-case/update-test-case.js +2 -1
- package/dist/qtm4j/tool/test-cycle/create-test-cycle.js +81 -0
- package/dist/qtm4j/tool/test-cycle/get-linked-requirements.js +71 -0
- package/dist/qtm4j/tool/test-cycle/link-requirements.js +91 -0
- package/dist/qtm4j/tool/test-cycle/link-testcases.js +118 -0
- package/dist/qtm4j/tool/test-cycle/search-linked-testcases.js +114 -0
- package/dist/qtm4j/tool/test-cycle/search-test-cycle.js +137 -0
- package/dist/qtm4j/tool/test-cycle/unlink-requirements.js +87 -0
- package/dist/qtm4j/tool/test-cycle/unlink-testcases.js +103 -0
- package/dist/qtm4j/tool/test-cycle/update-test-cycle.js +162 -0
- package/dist/reflect/client.js +15 -24
- package/dist/reflect/config/constants.js +0 -2
- package/dist/reflect/tool/recording/add-prompt-step.js +1 -0
- package/dist/reflect/tool/recording/add-segment.js +1 -0
- package/dist/reflect/tool/recording/connect-to-session.js +1 -0
- package/dist/reflect/tool/recording/delete-previous-step.js +1 -0
- package/dist/reflect/tool/recording/get-screenshot.js +1 -0
- package/dist/reflect/tool/suites/cancel-suite-execution.js +1 -0
- package/dist/reflect/tool/suites/execute-suite.js +1 -0
- package/dist/reflect/tool/suites/get-suite-execution-status.js +1 -0
- package/dist/reflect/tool/suites/list-suite-executions.js +1 -0
- package/dist/reflect/tool/suites/list-suites.js +1 -0
- package/dist/reflect/tool/tests/get-test-status.js +1 -0
- package/dist/reflect/tool/tests/list-segments.js +1 -0
- package/dist/reflect/tool/tests/list-tests.js +1 -0
- package/dist/reflect/tool/tests/run-test.js +1 -0
- package/dist/swagger/client/portal-types.js +1 -1
- package/dist/swagger/client/tools.js +23 -0
- package/dist/swagger/client.js +25 -28
- package/dist/zephyr/client.js +14 -21
- package/dist/zephyr/tool/environment/get-environments.js +1 -0
- package/dist/zephyr/tool/folder/create-folder.js +1 -0
- package/dist/zephyr/tool/issue-link/get-test-cases.js +1 -0
- package/dist/zephyr/tool/issue-link/get-test-cycles.js +1 -0
- package/dist/zephyr/tool/issue-link/get-test-executions.js +1 -0
- package/dist/zephyr/tool/priority/get-priorities.js +1 -0
- package/dist/zephyr/tool/project/get-project.js +1 -0
- package/dist/zephyr/tool/project/get-projects.js +1 -0
- package/dist/zephyr/tool/status/get-statuses.js +1 -0
- package/dist/zephyr/tool/test-case/create-issue-link.js +1 -0
- package/dist/zephyr/tool/test-case/create-test-case.js +1 -0
- package/dist/zephyr/tool/test-case/create-test-script.js +1 -0
- package/dist/zephyr/tool/test-case/create-test-steps.js +1 -0
- package/dist/zephyr/tool/test-case/create-web-link.js +1 -0
- package/dist/zephyr/tool/test-case/get-links.js +1 -0
- package/dist/zephyr/tool/test-case/get-test-case.js +1 -0
- package/dist/zephyr/tool/test-case/get-test-cases.js +1 -0
- package/dist/zephyr/tool/test-case/get-test-script.js +1 -0
- package/dist/zephyr/tool/test-case/get-test-steps.js +1 -0
- package/dist/zephyr/tool/test-case/update-test-case.js +1 -0
- package/dist/zephyr/tool/test-cycle/create-issue-link.js +1 -0
- package/dist/zephyr/tool/test-cycle/create-test-cycle.js +1 -0
- package/dist/zephyr/tool/test-cycle/create-web-link.js +1 -0
- package/dist/zephyr/tool/test-cycle/get-links.js +1 -0
- package/dist/zephyr/tool/test-cycle/get-test-cycle.js +1 -0
- package/dist/zephyr/tool/test-cycle/get-test-cycles.js +1 -0
- package/dist/zephyr/tool/test-cycle/update-test-cycle.js +1 -0
- package/dist/zephyr/tool/test-execution/create-issue-link.js +1 -0
- package/dist/zephyr/tool/test-execution/create-test-execution.js +1 -0
- package/dist/zephyr/tool/test-execution/get-test-execution-links.js +1 -0
- package/dist/zephyr/tool/test-execution/get-test-execution.js +1 -0
- package/dist/zephyr/tool/test-execution/get-test-executions.js +1 -0
- package/dist/zephyr/tool/test-execution/get-test-steps.js +1 -0
- package/dist/zephyr/tool/test-execution/update-test-execution.js +1 -0
- package/dist/zephyr/tool/test-execution/update-test-steps.js +1 -0
- package/package.json +1 -1
- package/dist/common/request-context.js +0 -20
|
@@ -13,8 +13,41 @@ const ENDPOINTS = {
|
|
|
13
13
|
SEARCH_TEST_CASES: `${API_CONFIG.API_VERSION}/testcases/search`,
|
|
14
14
|
/** Resolve test case keys → internal UIDs for a given project */
|
|
15
15
|
RESOLVE_TEST_CASE_IDS: (projectId) => `${API_CONFIG.API_VERSION}/projects/${projectId}/mcp/testcases/resolve-ids`,
|
|
16
|
+
/** Update test cycle endpoint */
|
|
17
|
+
UPDATE_TEST_CYCLE: (id) => `${API_CONFIG.API_VERSION}/testcycles/${id}`,
|
|
18
|
+
/** Create test cycle endpoint */
|
|
19
|
+
CREATE_TEST_CYCLE: `${API_CONFIG.API_VERSION}/testcycles`,
|
|
20
|
+
/** Search test cycles endpoint */
|
|
21
|
+
SEARCH_TEST_CYCLES: `${API_CONFIG.API_VERSION}/testcycles/search`,
|
|
16
22
|
/** Update test case endpoint */
|
|
17
23
|
UPDATE_TEST_CASE: (id, versionNo) => `${API_CONFIG.API_VERSION}/testcases/${id}/versions/${versionNo}`,
|
|
24
|
+
RESOLVE_TEST_CYCLE_IDS: (projectId) => `${API_CONFIG.API_VERSION}/projects/${projectId}/mcp/testcycles/resolve-ids`,
|
|
25
|
+
/** Resolve requirement keys → internal Jira issue IDs for a given project */
|
|
26
|
+
RESOLVE_REQUIREMENT_IDS: (projectId) => `${API_CONFIG.API_VERSION}/projects/${projectId}/mcp/requirement/resolve-ids`,
|
|
27
|
+
/** Link requirements to test case endpoint */
|
|
28
|
+
LINK_REQUIREMENTS: (id, versionNo) => `${API_CONFIG.API_VERSION}/testcases/${id}/version/${versionNo}/requirements/link`,
|
|
29
|
+
/** Unlink requirements from test case endpoint */
|
|
30
|
+
UNLINK_REQUIREMENTS: (id, versionNo) => `${API_CONFIG.API_VERSION}/testcases/${id}/versions/${versionNo}/requirements/unlink`,
|
|
31
|
+
/** Link test cases to requirement endpoint */
|
|
32
|
+
LINK_TESTCASES_TO_REQUIREMENT: (requirementId) => `${API_CONFIG.API_VERSION}/requirements/${requirementId}/testcases/link`,
|
|
33
|
+
/** Unlink test cases from requirement endpoint */
|
|
34
|
+
UNLINK_TESTCASES_FROM_REQUIREMENT: (requirementId) => `${API_CONFIG.API_VERSION}/requirements/${requirementId}/testcases/unlink`,
|
|
35
|
+
/** Get linked requirements for a test case endpoint */
|
|
36
|
+
GET_LINKED_REQUIREMENTS: (id) => `${API_CONFIG.API_VERSION}/testcases/${id}/requirements`,
|
|
37
|
+
/** Get linked test cases for a requirement endpoint */
|
|
38
|
+
GET_LINKED_TESTCASES_FOR_REQUIREMENT: (requirementId) => `${API_CONFIG.API_VERSION}/requirements/${requirementId}/testcases`,
|
|
39
|
+
/** Link test cases to test cycle endpoint */
|
|
40
|
+
LINK_TESTCASES_TO_CYCLE: (cycleId) => `${API_CONFIG.API_VERSION}/testcycles/${cycleId}/testcases`,
|
|
41
|
+
/** Unlink test cases from test cycle endpoint */
|
|
42
|
+
UNLINK_TESTCASES_FROM_CYCLE: (cycleId) => `${API_CONFIG.API_VERSION}/testcycles/${cycleId}/testcases`,
|
|
43
|
+
/** Search test cases linked to a test cycle endpoint */
|
|
44
|
+
SEARCH_LINKED_TESTCASES_IN_CYCLE: (cycleId) => `${API_CONFIG.API_VERSION}/testcycles/${cycleId}/testcases/search`,
|
|
45
|
+
/** Get linked requirements for a test cycle endpoint */
|
|
46
|
+
GET_LINKED_REQUIREMENTS_FOR_CYCLE: (cycleId) => `${API_CONFIG.API_VERSION}/testcycles/${cycleId}/requirements`,
|
|
47
|
+
/** Link requirements to test cycle endpoint */
|
|
48
|
+
LINK_REQUIREMENTS_TO_CYCLE: (cycleId) => `${API_CONFIG.API_VERSION}/testcycles/${cycleId}/requirements/link`,
|
|
49
|
+
/** Unlink requirements from test cycle endpoint */
|
|
50
|
+
UNLINK_REQUIREMENTS_FROM_CYCLE: (cycleId) => `${API_CONFIG.API_VERSION}/testcycles/${cycleId}/requirements/unlink`,
|
|
18
51
|
/** Test steps search endpoint */
|
|
19
52
|
TEST_STEPS: (id, versionNo) => `${API_CONFIG.API_VERSION}/testcases/${id}/versions/${versionNo}/teststeps/search`,
|
|
20
53
|
/** Common attributes endpoint (priority, statuses) */
|
|
@@ -22,7 +55,13 @@ const ENDPOINTS = {
|
|
|
22
55
|
/** Labels search endpoint */
|
|
23
56
|
LABELS: (projectId) => `${API_CONFIG.API_VERSION}/projects/${projectId}/mcp/labels`,
|
|
24
57
|
/** Components search endpoint */
|
|
25
|
-
COMPONENTS: (projectId) => `${API_CONFIG.API_VERSION}/projects/${projectId}/mcp/components
|
|
58
|
+
COMPONENTS: (projectId) => `${API_CONFIG.API_VERSION}/projects/${projectId}/mcp/components`,
|
|
59
|
+
/** Automation: initiate result file import — returns pre-signed S3 upload URL + trackingId */
|
|
60
|
+
AUTOMATION_IMPORT: "/rest/api/automation/importresult",
|
|
61
|
+
/** Automation: poll import progress by trackingId */
|
|
62
|
+
AUTOMATION_IMPORT_TRACK: "/rest/api/automation/importresult/track",
|
|
63
|
+
/** Automation: paginated history of past automation result uploads */
|
|
64
|
+
AUTOMATION_HISTORY: "/rest/api/automation/importresult/history"
|
|
26
65
|
};
|
|
27
66
|
const HTTP_HEADERS = {
|
|
28
67
|
/** API key header name */
|
|
@@ -38,12 +77,15 @@ const HTTP_HEADERS = {
|
|
|
38
77
|
};
|
|
39
78
|
const CONTENT_TYPES = {
|
|
40
79
|
/** JSON content type */
|
|
41
|
-
JSON: "application/json"
|
|
80
|
+
JSON: "application/json",
|
|
81
|
+
/** Multipart form-data content type (used for S3 automation file uploads) */
|
|
82
|
+
MULTIPART: "multipart/form-data"
|
|
42
83
|
};
|
|
43
84
|
const HTTP_METHODS = {
|
|
44
85
|
GET: "GET",
|
|
45
86
|
POST: "POST",
|
|
46
|
-
PUT: "PUT"
|
|
87
|
+
PUT: "PUT",
|
|
88
|
+
DELETE: "DELETE"
|
|
47
89
|
};
|
|
48
90
|
const HTTP_STATUS = {
|
|
49
91
|
/** No content status code */
|
|
@@ -72,14 +114,24 @@ const PAGINATION = {
|
|
|
72
114
|
DEFAULT_MAX_RESULTS_TEST_STEPS: 50,
|
|
73
115
|
/** Maximum allowed results per request for test steps */
|
|
74
116
|
MAX_ALLOWED_RESULTS_TEST_STEPS: 100,
|
|
117
|
+
/** Default maximum results for test cycles */
|
|
118
|
+
DEFAULT_MAX_RESULTS_TEST_CYCLES: 20,
|
|
119
|
+
/** Maximum allowed results per request for test cycles */
|
|
120
|
+
MAX_ALLOWED_RESULTS_TEST_CYCLES: 100,
|
|
75
121
|
/** Minimum allowed results per request */
|
|
76
122
|
MIN_ALLOWED_RESULTS: 1
|
|
77
123
|
};
|
|
124
|
+
const AUTOMATION_LIMITS = {
|
|
125
|
+
/** Maximum allowed upload file size in bytes (10 MB) */
|
|
126
|
+
MAX_FILE_SIZE_BYTES: 10 * 1024 * 1024
|
|
127
|
+
};
|
|
78
128
|
const ERROR_MESSAGES = {
|
|
79
129
|
/** Client not configured error */
|
|
80
130
|
CLIENT_NOT_CONFIGURED: "QTM4J client not configured. Please set API key.",
|
|
81
131
|
/** Request failed template */
|
|
82
|
-
REQUEST_FAILED: (status, errorText) => `Request failed with status ${status}: ${errorText}
|
|
132
|
+
REQUEST_FAILED: (status, errorText) => `Request failed with status ${status}: ${errorText}`,
|
|
133
|
+
/** Automation API key not configured */
|
|
134
|
+
AUTOMATION_API_KEY_NOT_CONFIGURED: "QTM4J Automation API key not configured. Set the QTM4J_AUTOMATION_API_KEY environment variable or pass the Qtm4j-Automation-Api-Key header."
|
|
83
135
|
};
|
|
84
136
|
const TOOL_NAMES = {
|
|
85
137
|
/** Get Projects tool */
|
|
@@ -111,17 +163,117 @@ const TOOL_NAMES = {
|
|
|
111
163
|
UPDATE_TEST_CASE: {
|
|
112
164
|
TITLE: "Update Test Case",
|
|
113
165
|
SUMMARY: "Update an existing test case in QTM4J. Supports auto-resolving human-readable names for priority, status, labels, and components. Labels and components support add/delete operations."
|
|
166
|
+
},
|
|
167
|
+
/** Upload Automation Result tool */
|
|
168
|
+
UPLOAD_AUTOMATION_RESULT: {
|
|
169
|
+
TITLE: "Upload Automation Result",
|
|
170
|
+
SUMMARY: "Upload an automation result file to QTM4J and map the results to a test cycle. Supports JUnit XML, TestNG XML, Cucumber JSON, QAF, HP UFT, and SpecFlow formats."
|
|
171
|
+
},
|
|
172
|
+
/** Get Automation History tool */
|
|
173
|
+
GET_AUTOMATION_HISTORY: {
|
|
174
|
+
TITLE: "Get Automation History",
|
|
175
|
+
SUMMARY: "Retrieve a paginated history of past automation result uploads for a QTM4J project."
|
|
176
|
+
},
|
|
177
|
+
/** Search Test Cycles tool */
|
|
178
|
+
SEARCH_TEST_CYCLES: {
|
|
179
|
+
TITLE: "Search Test Cycles",
|
|
180
|
+
SUMMARY: "Search for test cycles in a QTM4J project by status, owner, folder, date range, or keyword. projectId is injected automatically from the active project context."
|
|
181
|
+
},
|
|
182
|
+
/** Create Test Cycle tool */
|
|
183
|
+
CREATE_TEST_CYCLE: {
|
|
184
|
+
TITLE: "Create Test Cycle",
|
|
185
|
+
SUMMARY: "Create a new test cycle in a QTM4J project. Supports auto-resolving human-readable names for priority and status. Always creates in the 'MCP Generated' folder. projectId is injected automatically from the active project context."
|
|
186
|
+
},
|
|
187
|
+
/** Update Test Cycle tool */
|
|
188
|
+
UPDATE_TEST_CYCLE: {
|
|
189
|
+
TITLE: "Update Test Cycle",
|
|
190
|
+
SUMMARY: "Update an existing test cycle in QTM4J by its human-readable key (e.g. 'SCRUM-TR-101'). Supports auto-resolving human-readable names for status and priority. Labels and components support add/delete operations. Only the fields you provide are changed — omitted fields are left as-is. projectId is injected automatically from the active project context."
|
|
191
|
+
},
|
|
192
|
+
/** Link Requirements tool */
|
|
193
|
+
LINK_REQUIREMENTS: {
|
|
194
|
+
TITLE: "Link Requirements to Test Case",
|
|
195
|
+
SUMMARY: "Link one or more Jira requirements to a test case in QTM4J by requirement keys or JQL filter. Requirement keys are resolved to internal IDs automatically."
|
|
196
|
+
},
|
|
197
|
+
/** Unlink Requirements tool */
|
|
198
|
+
UNLINK_REQUIREMENTS: {
|
|
199
|
+
TITLE: "Unlink Requirements from Test Case",
|
|
200
|
+
SUMMARY: "Unlink one or more Jira requirements from a test case in QTM4J by requirement keys, or unlink all requirements at once with unLinkAll."
|
|
201
|
+
},
|
|
202
|
+
/** Link Test Cases to Requirement tool */
|
|
203
|
+
LINK_TESTCASES_TO_REQUIREMENT: {
|
|
204
|
+
TITLE: "Link Test Cases to Requirement",
|
|
205
|
+
SUMMARY: "Link test cases to a Jira requirement in QTM4J by test case keys or filter criteria. Test case keys are resolved to internal IDs automatically."
|
|
206
|
+
},
|
|
207
|
+
/** Unlink Test Cases from Requirement tool */
|
|
208
|
+
UNLINK_TESTCASES_FROM_REQUIREMENT: {
|
|
209
|
+
TITLE: "Unlink Test Cases from Requirement",
|
|
210
|
+
SUMMARY: "Unlink test cases from a Jira requirement in QTM4J by test case keys or filter criteria. Test case keys are resolved to internal IDs automatically."
|
|
211
|
+
},
|
|
212
|
+
/** Get Linked Requirements tool */
|
|
213
|
+
GET_LINKED_REQUIREMENTS: {
|
|
214
|
+
TITLE: "Get Linked Requirements",
|
|
215
|
+
SUMMARY: "Retrieve the Jira requirements linked to a specific test case in QTM4J. Test case key is resolved to internal ID automatically."
|
|
216
|
+
},
|
|
217
|
+
/** Get Linked Test Cases for Requirement tool */
|
|
218
|
+
GET_LINKED_TESTCASES_FOR_REQUIREMENT: {
|
|
219
|
+
TITLE: "Get Linked Test Cases for Requirement",
|
|
220
|
+
SUMMARY: "Retrieve the test cases linked to a Jira requirement in QTM4J. Requirement key is resolved to internal ID automatically."
|
|
221
|
+
},
|
|
222
|
+
/** Link Test Cases to Test Cycle tool */
|
|
223
|
+
LINK_TESTCASES_TO_CYCLE: {
|
|
224
|
+
TITLE: "Link Test Cases to Test Cycle",
|
|
225
|
+
SUMMARY: "Link test cases to a QTM4J test cycle by test case keys or filter criteria. Test case keys are resolved to internal IDs and latest versions automatically."
|
|
226
|
+
},
|
|
227
|
+
/** Unlink Test Cases from Test Cycle tool */
|
|
228
|
+
UNLINK_TESTCASES_FROM_CYCLE: {
|
|
229
|
+
TITLE: "Unlink Test Cases from Test Cycle",
|
|
230
|
+
SUMMARY: "Unlink test cases from a QTM4J test cycle by test case keys, filter criteria, or all at once with unlinkAll."
|
|
231
|
+
},
|
|
232
|
+
/** Search Linked Test Cases in Test Cycle tool */
|
|
233
|
+
SEARCH_LINKED_TESTCASES_IN_CYCLE: {
|
|
234
|
+
TITLE: "Search Linked Test Cases in Test Cycle",
|
|
235
|
+
SUMMARY: "Search and filter test case executions linked to a QTM4J test cycle. Supports pagination, field selection, sorting, and rich filter criteria."
|
|
236
|
+
},
|
|
237
|
+
/** Get Linked Requirements for Test Cycle tool */
|
|
238
|
+
GET_LINKED_REQUIREMENTS_FOR_CYCLE: {
|
|
239
|
+
TITLE: "Get Linked Requirements for Test Cycle",
|
|
240
|
+
SUMMARY: "Retrieve Jira requirements linked to a QTM4J test cycle. Test cycle key is resolved to internal UID automatically."
|
|
241
|
+
},
|
|
242
|
+
/** Link Requirements to Test Cycle tool */
|
|
243
|
+
LINK_REQUIREMENTS_TO_CYCLE: {
|
|
244
|
+
TITLE: "Link Requirements to Test Cycle",
|
|
245
|
+
SUMMARY: "Link one or more Jira requirements to a QTM4J test cycle by requirement keys or JQL filter. Requirement keys are resolved to internal IDs automatically."
|
|
246
|
+
},
|
|
247
|
+
/** Unlink Requirements from Test Cycle tool */
|
|
248
|
+
UNLINK_REQUIREMENTS_FROM_CYCLE: {
|
|
249
|
+
TITLE: "Unlink Requirements from Test Cycle",
|
|
250
|
+
SUMMARY: "Unlink one or more Jira requirements from a QTM4J test cycle by requirement keys, or unlink all requirements at once with unLinkAll."
|
|
114
251
|
}
|
|
115
252
|
};
|
|
253
|
+
const TOOLSETS = {
|
|
254
|
+
/** Test Automation toolset */
|
|
255
|
+
TEST_AUTOMATION: "Test Automation",
|
|
256
|
+
/** Test Cases toolset */
|
|
257
|
+
TEST_CASES: "Test Cases",
|
|
258
|
+
/** Test Cycle Management toolset */
|
|
259
|
+
TEST_CYCLES: "Test Cycles",
|
|
260
|
+
/** Projects toolset */
|
|
261
|
+
PROJECTS: "Projects",
|
|
262
|
+
REQUIREMENTS: "Requirements"
|
|
263
|
+
};
|
|
116
264
|
const CONFIG_KEYS = {
|
|
117
265
|
/** API key configuration key */
|
|
118
266
|
API_KEY: "api_key",
|
|
267
|
+
/** Automation API key configuration key */
|
|
268
|
+
AUTOMATION_API_KEY: "automation_api_key",
|
|
119
269
|
/** Base URL configuration key */
|
|
120
270
|
BASE_URL: "base_url"
|
|
121
271
|
};
|
|
122
272
|
const SCHEMA_DESCRIPTIONS = {
|
|
123
273
|
/** API key description */
|
|
124
274
|
API_KEY: "QTM4J API key for authentication",
|
|
275
|
+
/** Automation API key description */
|
|
276
|
+
AUTOMATION_API_KEY: "QTM4J Automation API key for uploading automation result files. This is a separate key from the regular API key and can be found in QTM4J under Automation settings.",
|
|
125
277
|
/** Base URL description */
|
|
126
278
|
BASE_URL: "QTM4J base URL (default: https://qtmcloud.qmetry.com). Can be customized for on-premise installations.",
|
|
127
279
|
/** Start at description */
|
|
@@ -133,8 +285,40 @@ const SCHEMA_DESCRIPTIONS = {
|
|
|
133
285
|
/** QMetry enabled description */
|
|
134
286
|
QMETRY_ENABLED: "Filter by QMetry enabled status",
|
|
135
287
|
/** Project object description */
|
|
136
|
-
PROJECT_OBJECT: "Project object"
|
|
288
|
+
PROJECT_OBJECT: "Project object",
|
|
289
|
+
/** Automation result file path */
|
|
290
|
+
AUTOMATION_FILE_PATH: "Path to the automation result file on disk. Filesystem contents can change between turns — always resolve this from a fresh scan, never from a previously seen path. Supported extensions: .xml, .json, .zip",
|
|
291
|
+
/** Automation result format */
|
|
292
|
+
AUTOMATION_FORMAT: "Format of the result file. Supported values: cucumber, testng, junit, qaf, hpuft, specflow",
|
|
293
|
+
/** Test cycle to reuse */
|
|
294
|
+
AUTOMATION_TEST_CYCLE_TO_REUSE: "Work key of an existing test cycle to reuse (e.g. 'TR-PRJ-1'). If omitted, a new test cycle is created.",
|
|
295
|
+
/** Automation environment */
|
|
296
|
+
AUTOMATION_ENVIRONMENT: "Name of the environment on which the test cycle was executed (e.g. 'Chrome', 'Staging'). Defaults to 'No Environment'.",
|
|
297
|
+
/** Automation build */
|
|
298
|
+
AUTOMATION_BUILD: "Build name or version for the test cycle execution (e.g. '1.0.0-beta'). Defaults to blank.",
|
|
299
|
+
/** isZip flag */
|
|
300
|
+
AUTOMATION_IS_ZIP: "Set to true when uploading a ZIP archive containing result files. Required for QAF format.",
|
|
301
|
+
/** attachFile flag */
|
|
302
|
+
AUTOMATION_ATTACH_FILE: "Set to true to upload attachments referenced in execution results.",
|
|
303
|
+
/** matchTestSteps flag */
|
|
304
|
+
AUTOMATION_MATCH_TEST_STEPS: "true — match test cases by summary AND test steps. false — match by summary or key only.",
|
|
305
|
+
/** appendTestName flag */
|
|
306
|
+
AUTOMATION_APPEND_TEST_NAME: "Applicable to JUnit/TestNG only. Appends suite/test name to method name in test case summary.",
|
|
307
|
+
/** fields object */
|
|
308
|
+
AUTOMATION_FIELDS: "Additional fields to set on the test cycle, test case, and/or test case execution created during import.",
|
|
309
|
+
/** getAutomationHistory — pagination */
|
|
310
|
+
AUTOMATION_HISTORY_START_AT: "Zero-indexed starting position for pagination (default: 0).",
|
|
311
|
+
AUTOMATION_HISTORY_MAX_RESULTS: "Maximum number of records to return per page (default: 20, max: 100)."
|
|
137
312
|
};
|
|
313
|
+
const AUTOMATION_RESULT_DIRS = [
|
|
314
|
+
"target/surefire-reports",
|
|
315
|
+
"target/failsafe-reports",
|
|
316
|
+
"build/reports/tests",
|
|
317
|
+
"build/test-results",
|
|
318
|
+
"test-results",
|
|
319
|
+
"reports",
|
|
320
|
+
"cucumber-reports"
|
|
321
|
+
];
|
|
138
322
|
const RESPONSE_FIELDS = {
|
|
139
323
|
/** Start at field */
|
|
140
324
|
START_AT: "startAt",
|
|
@@ -143,6 +327,10 @@ const RESPONSE_FIELDS = {
|
|
|
143
327
|
FIELDS: "fields",
|
|
144
328
|
SORT: "sort"
|
|
145
329
|
};
|
|
330
|
+
const SORT_DEFAULTS = {
|
|
331
|
+
/** Default sort expression for test cycle search */
|
|
332
|
+
TEST_CYCLES: "key:asc"
|
|
333
|
+
};
|
|
146
334
|
const EMPTY_VALUES = {
|
|
147
335
|
/** Empty object */
|
|
148
336
|
OBJECT: {},
|
|
@@ -153,6 +341,8 @@ const EMPTY_VALUES = {
|
|
|
153
341
|
};
|
|
154
342
|
export {
|
|
155
343
|
API_CONFIG,
|
|
344
|
+
AUTOMATION_LIMITS,
|
|
345
|
+
AUTOMATION_RESULT_DIRS,
|
|
156
346
|
CLIENT_CONFIG,
|
|
157
347
|
CONFIG_KEYS,
|
|
158
348
|
CONTENT_TYPES,
|
|
@@ -165,5 +355,7 @@ export {
|
|
|
165
355
|
PAGINATION,
|
|
166
356
|
RESPONSE_FIELDS,
|
|
167
357
|
SCHEMA_DESCRIPTIONS,
|
|
358
|
+
SORT_DEFAULTS,
|
|
359
|
+
TOOLSETS,
|
|
168
360
|
TOOL_NAMES
|
|
169
361
|
};
|
|
@@ -8,7 +8,8 @@ const ResolverKeys = {
|
|
|
8
8
|
TEST_PLAN_STATUS: "testplan_status",
|
|
9
9
|
TEST_CYCLE_STATUS: "testcycle_status",
|
|
10
10
|
PRIORITY: "priority",
|
|
11
|
-
TESTCASE_FOLDER: "testcase_folder"
|
|
11
|
+
TESTCASE_FOLDER: "testcase_folder",
|
|
12
|
+
TEST_CYCLE_FOLDER: "testcycle_folder"
|
|
12
13
|
},
|
|
13
14
|
/**
|
|
14
15
|
* Fields with dedicated search APIs (fetched on-demand, not batch-loaded).
|
|
@@ -17,7 +18,9 @@ const ResolverKeys = {
|
|
|
17
18
|
SearchableField: {
|
|
18
19
|
LABEL: "label",
|
|
19
20
|
COMPONENTS: "components",
|
|
20
|
-
TEST_CASE_KEY_TO_UID: "testCaseKeyToUid"
|
|
21
|
+
TEST_CASE_KEY_TO_UID: "testCaseKeyToUid",
|
|
22
|
+
TEST_CYCLE_KEY_TO_UID: "testCycleKeyToUid",
|
|
23
|
+
REQUIREMENT_KEY_TO_ID: "requirementKeyToId"
|
|
21
24
|
}
|
|
22
25
|
};
|
|
23
26
|
var InputField = /* @__PURE__ */ ((InputField2) => {
|
|
@@ -4,13 +4,15 @@ import { AuthService } from "./auth-service.js";
|
|
|
4
4
|
class ApiClient {
|
|
5
5
|
baseUrl;
|
|
6
6
|
tokenProvider;
|
|
7
|
-
|
|
7
|
+
automationTokenProvider;
|
|
8
|
+
constructor(tokenOrProvider, baseUrl, automationTokenProvider) {
|
|
8
9
|
this.baseUrl = baseUrl.trim().replace(/\/$/, EMPTY_VALUES.STRING);
|
|
9
10
|
if (typeof tokenOrProvider === "string") {
|
|
10
11
|
this.tokenProvider = () => tokenOrProvider;
|
|
11
12
|
} else {
|
|
12
13
|
this.tokenProvider = tokenOrProvider;
|
|
13
14
|
}
|
|
15
|
+
this.automationTokenProvider = automationTokenProvider;
|
|
14
16
|
}
|
|
15
17
|
/**
|
|
16
18
|
* Get authentication headers for current request
|
|
@@ -25,6 +27,17 @@ class ApiClient {
|
|
|
25
27
|
}
|
|
26
28
|
return new AuthService(token).getAuthHeaders();
|
|
27
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Get authentication headers using the automation API key.
|
|
32
|
+
* @throws ToolError if automation API key is not configured
|
|
33
|
+
*/
|
|
34
|
+
getAutomationHeaders() {
|
|
35
|
+
const token = this.automationTokenProvider?.();
|
|
36
|
+
if (!token) {
|
|
37
|
+
throw new ToolError(ERROR_MESSAGES.AUTOMATION_API_KEY_NOT_CONFIGURED);
|
|
38
|
+
}
|
|
39
|
+
return new AuthService(token).getAuthHeaders();
|
|
40
|
+
}
|
|
28
41
|
/**
|
|
29
42
|
* Construct full URL with query parameters
|
|
30
43
|
* @param endpoint - API endpoint path
|
|
@@ -59,10 +72,11 @@ class ApiClient {
|
|
|
59
72
|
* Perform POST request
|
|
60
73
|
* @param endpoint - API endpoint path
|
|
61
74
|
* @param body - Request body object
|
|
75
|
+
* @param params - Optional query parameters
|
|
62
76
|
* @returns Parsed response data
|
|
63
77
|
*/
|
|
64
|
-
async post(endpoint, body) {
|
|
65
|
-
const response = await fetch(this.getUrl(endpoint), {
|
|
78
|
+
async post(endpoint, body, params) {
|
|
79
|
+
const response = await fetch(this.getUrl(endpoint, params), {
|
|
66
80
|
method: HTTP_METHODS.POST,
|
|
67
81
|
headers: {
|
|
68
82
|
...this.getHeaders(),
|
|
@@ -89,6 +103,79 @@ class ApiClient {
|
|
|
89
103
|
});
|
|
90
104
|
return await this.validateAndGetResponseBody(response);
|
|
91
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Perform GET request using the automation API key (QTM4J_AUTOMATION_API_KEY).
|
|
108
|
+
* Used for automation endpoints that require the automation key instead of the regular API key.
|
|
109
|
+
* @param endpoint - API endpoint path
|
|
110
|
+
* @param params - Optional query parameters
|
|
111
|
+
* @returns Parsed response data
|
|
112
|
+
*/
|
|
113
|
+
async getAutomation(endpoint, params) {
|
|
114
|
+
const response = await fetch(this.getUrl(endpoint, params), {
|
|
115
|
+
method: HTTP_METHODS.GET,
|
|
116
|
+
headers: this.getAutomationHeaders()
|
|
117
|
+
});
|
|
118
|
+
return await this.validateAndGetResponseBody(response);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Perform POST request using the automation API key (QTM4J_AUTOMATION_API_KEY).
|
|
122
|
+
* Used for automation import endpoints — same apiKey header as all other APIs,
|
|
123
|
+
* but the value is the automation key instead of the regular API key.
|
|
124
|
+
* @param endpoint - API endpoint path
|
|
125
|
+
* @param body - Request body object
|
|
126
|
+
* @returns Parsed response data
|
|
127
|
+
*/
|
|
128
|
+
async postAutomation(endpoint, body) {
|
|
129
|
+
const url = this.getUrl(endpoint);
|
|
130
|
+
const requestHeaders = {
|
|
131
|
+
...this.getAutomationHeaders(),
|
|
132
|
+
[HTTP_HEADERS.CONTENT_TYPE]: CONTENT_TYPES.JSON
|
|
133
|
+
};
|
|
134
|
+
const response = await fetch(url, {
|
|
135
|
+
method: HTTP_METHODS.POST,
|
|
136
|
+
headers: requestHeaders,
|
|
137
|
+
body: JSON.stringify(body)
|
|
138
|
+
});
|
|
139
|
+
return await this.validateAndGetResponseBody(response);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Perform DELETE request with optional body
|
|
143
|
+
* @param endpoint - API endpoint path
|
|
144
|
+
* @param body - Optional request body object
|
|
145
|
+
* @returns Parsed response data
|
|
146
|
+
*/
|
|
147
|
+
async delete(endpoint, body) {
|
|
148
|
+
const response = await fetch(this.getUrl(endpoint), {
|
|
149
|
+
method: HTTP_METHODS.DELETE,
|
|
150
|
+
headers: {
|
|
151
|
+
...this.getHeaders(),
|
|
152
|
+
[HTTP_HEADERS.CONTENT_TYPE]: CONTENT_TYPES.JSON
|
|
153
|
+
},
|
|
154
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
155
|
+
});
|
|
156
|
+
return await this.validateAndGetResponseBody(response);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Upload a file as multipart/form-data using the automation API key.
|
|
160
|
+
* Content-Type is not set manually — fetch sets it with the correct multipart boundary.
|
|
161
|
+
* @param uploadUrl - Full URL returned by the automation import initiation step
|
|
162
|
+
* @param fileBuffer - Raw file contents as a Buffer
|
|
163
|
+
*/
|
|
164
|
+
async uploadFileMultipart(uploadUrl, fileBuffer) {
|
|
165
|
+
const response = await fetch(uploadUrl, {
|
|
166
|
+
method: HTTP_METHODS.PUT,
|
|
167
|
+
headers: {
|
|
168
|
+
[HTTP_HEADERS.CONTENT_TYPE]: CONTENT_TYPES.MULTIPART
|
|
169
|
+
},
|
|
170
|
+
body: new Uint8Array(fileBuffer)
|
|
171
|
+
});
|
|
172
|
+
if (!response.ok) {
|
|
173
|
+
const errorText = await response.text();
|
|
174
|
+
throw new ToolError(
|
|
175
|
+
ERROR_MESSAGES.REQUEST_FAILED(response.status, errorText)
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
92
179
|
/**
|
|
93
180
|
* Validate HTTP response and extract body
|
|
94
181
|
* Handles various response types: JSON, text, empty responses
|
|
@@ -19,7 +19,7 @@ class Cache {
|
|
|
19
19
|
if (!this.trackedKeys.has(projectKey)) {
|
|
20
20
|
this.trackedKeys.set(projectKey, /* @__PURE__ */ new Set());
|
|
21
21
|
}
|
|
22
|
-
this.trackedKeys.get(projectKey)
|
|
22
|
+
this.trackedKeys.get(projectKey)?.add(key);
|
|
23
23
|
}
|
|
24
24
|
has(projectKey, fieldKey) {
|
|
25
25
|
return this.cacheService.get(this.compositeKey(projectKey, fieldKey)) !== void 0;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { CommonAttributeResolver } from "./resolvers/common-attribute-resolver.js";
|
|
2
2
|
import { ComponentResolver } from "./resolvers/component-resolver.js";
|
|
3
3
|
import { LabelResolver } from "./resolvers/label-resolver.js";
|
|
4
|
+
import { RequirementIdResolver } from "./resolvers/requirement-id-resolver.js";
|
|
4
5
|
import { TestCaseUidResolver } from "./resolvers/test-case-uid-resolver.js";
|
|
6
|
+
import { TestCycleUidResolver } from "./resolvers/test-cycle-uid-resolver.js";
|
|
5
7
|
const ERROR_NO_PROJECT_CONTEXT = "No active project set. Please call set_project_context before performing this operation.";
|
|
6
8
|
class ResolverRegistry {
|
|
7
9
|
resolverByKey;
|
|
@@ -16,12 +18,16 @@ class ResolverRegistry {
|
|
|
16
18
|
this.testCaseUidResolver = new TestCaseUidResolver(apiClient);
|
|
17
19
|
const labelResolver = new LabelResolver(apiClient, cacheService);
|
|
18
20
|
const componentResolver = new ComponentResolver(apiClient, cacheService);
|
|
21
|
+
const requirementIdResolver = new RequirementIdResolver(apiClient);
|
|
22
|
+
const testcycleUidResolver = new TestCycleUidResolver(apiClient);
|
|
19
23
|
this.resolverByKey = /* @__PURE__ */ new Map();
|
|
20
24
|
for (const resolver of [
|
|
21
25
|
this.commonAttributes,
|
|
22
26
|
labelResolver,
|
|
23
27
|
componentResolver,
|
|
24
|
-
this.testCaseUidResolver
|
|
28
|
+
this.testCaseUidResolver,
|
|
29
|
+
requirementIdResolver,
|
|
30
|
+
testcycleUidResolver
|
|
25
31
|
]) {
|
|
26
32
|
for (const key of resolver.fieldKeys) {
|
|
27
33
|
this.resolverByKey.set(key, resolver);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ENDPOINTS } from "../../config/constants.js";
|
|
2
|
+
import { ResolverKeys } from "../../config/field-resolution.types.js";
|
|
3
|
+
import { Resolver } from "./resolver.js";
|
|
4
|
+
class RequirementIdResolver extends Resolver {
|
|
5
|
+
fieldKeys = [
|
|
6
|
+
ResolverKeys.SearchableField.REQUIREMENT_KEY_TO_ID
|
|
7
|
+
];
|
|
8
|
+
apiClient;
|
|
9
|
+
constructor(apiClient) {
|
|
10
|
+
super();
|
|
11
|
+
this.apiClient = apiClient;
|
|
12
|
+
}
|
|
13
|
+
async resolve(_inputField, _resolverKey, _body, _context, _warnings) {
|
|
14
|
+
}
|
|
15
|
+
async resolveAndReturn(projectId, keys) {
|
|
16
|
+
if (keys.length === 0) return {};
|
|
17
|
+
const response = await this.apiClient.get(
|
|
18
|
+
ENDPOINTS.RESOLVE_REQUIREMENT_IDS(projectId),
|
|
19
|
+
{ keys: keys.join(",") }
|
|
20
|
+
);
|
|
21
|
+
return response;
|
|
22
|
+
}
|
|
23
|
+
clearCache(_projectKey) {
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
RequirementIdResolver
|
|
28
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ENDPOINTS } from "../../config/constants.js";
|
|
2
|
+
import { ResolverKeys } from "../../config/field-resolution.types.js";
|
|
3
|
+
import { Resolver } from "./resolver.js";
|
|
4
|
+
class TestCycleUidResolver extends Resolver {
|
|
5
|
+
fieldKeys = [
|
|
6
|
+
ResolverKeys.SearchableField.TEST_CYCLE_KEY_TO_UID
|
|
7
|
+
];
|
|
8
|
+
apiClient;
|
|
9
|
+
constructor(apiClient) {
|
|
10
|
+
super();
|
|
11
|
+
this.apiClient = apiClient;
|
|
12
|
+
}
|
|
13
|
+
async resolve(_inputField, _resolverKey, _body, _context, _warnings) {
|
|
14
|
+
}
|
|
15
|
+
async resolveAndReturn(projectId, keys) {
|
|
16
|
+
if (keys.length === 0) return {};
|
|
17
|
+
const response = await this.apiClient.get(
|
|
18
|
+
ENDPOINTS.RESOLVE_TEST_CYCLE_IDS(projectId),
|
|
19
|
+
{ keys: keys.join(",") }
|
|
20
|
+
);
|
|
21
|
+
return response;
|
|
22
|
+
}
|
|
23
|
+
clearCache(_projectKey) {
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export {
|
|
27
|
+
TestCycleUidResolver
|
|
28
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import zod__default from "zod";
|
|
2
|
+
import { SCHEMA_DESCRIPTIONS } from "../config/constants.js";
|
|
3
|
+
const TestCycleFields = zod__default.object({
|
|
4
|
+
labels: zod__default.array(zod__default.string()).nullable().optional(),
|
|
5
|
+
components: zod__default.array(zod__default.string()).nullable().optional(),
|
|
6
|
+
priority: zod__default.string().nullable().optional(),
|
|
7
|
+
status: zod__default.string().nullable().optional(),
|
|
8
|
+
summary: zod__default.string().nullable().optional(),
|
|
9
|
+
description: zod__default.string().nullable().optional(),
|
|
10
|
+
assignee: zod__default.string().nullable().optional().describe(
|
|
11
|
+
"Jira Account ID of the assignee. Ask the user to provide their Account ID directly."
|
|
12
|
+
),
|
|
13
|
+
reporter: zod__default.string().nullable().optional().describe(
|
|
14
|
+
"Jira Account ID of the reporter. Ask the user to provide their Account ID directly."
|
|
15
|
+
),
|
|
16
|
+
folderId: zod__default.number().int().nullable().optional().describe(
|
|
17
|
+
"Numeric folder ID to place the test cycle in. Right-click a folder in QTM4J and select 'Copy Folder Id' to get this value."
|
|
18
|
+
),
|
|
19
|
+
plannedStartDate: zod__default.string().nullable().optional().describe("Date in 'dd/MMM/yyyy HH:mm' format, e.g. '14/May/2026 10:30'"),
|
|
20
|
+
plannedEndDate: zod__default.string().nullable().optional().describe("Date in 'dd/MMM/yyyy HH:mm' format, e.g. '14/May/2026 10:30'")
|
|
21
|
+
}).nullable().optional();
|
|
22
|
+
const TestCaseFields = zod__default.object({
|
|
23
|
+
labels: zod__default.array(zod__default.string()).nullable().optional(),
|
|
24
|
+
components: zod__default.array(zod__default.string()).nullable().optional(),
|
|
25
|
+
priority: zod__default.string().nullable().optional(),
|
|
26
|
+
status: zod__default.string().nullable().optional(),
|
|
27
|
+
description: zod__default.string().nullable().optional(),
|
|
28
|
+
precondition: zod__default.string().nullable().optional(),
|
|
29
|
+
assignee: zod__default.string().nullable().optional().describe(
|
|
30
|
+
"Jira Account ID of the assignee. Ask the user to provide their Account ID directly."
|
|
31
|
+
),
|
|
32
|
+
reporter: zod__default.string().nullable().optional().describe(
|
|
33
|
+
"Jira Account ID of the reporter. Ask the user to provide their Account ID directly."
|
|
34
|
+
),
|
|
35
|
+
estimatedTime: zod__default.string().nullable().optional(),
|
|
36
|
+
folderId: zod__default.number().int().nullable().optional().describe(
|
|
37
|
+
"Numeric folder ID to place the test cases in. Right-click a folder in QTM4J and select 'Copy Folder Id' to get this value."
|
|
38
|
+
)
|
|
39
|
+
}).nullable().optional();
|
|
40
|
+
const TestCaseExecutionFields = zod__default.object({
|
|
41
|
+
comment: zod__default.string().nullable().optional(),
|
|
42
|
+
actualTime: zod__default.string().nullable().optional(),
|
|
43
|
+
executionPlannedDate: zod__default.string().nullable().optional(),
|
|
44
|
+
assignee: zod__default.string().nullable().optional()
|
|
45
|
+
}).nullable().optional();
|
|
46
|
+
const UploadAutomationResultBody = zod__default.object({
|
|
47
|
+
filePath: zod__default.string().describe(SCHEMA_DESCRIPTIONS.AUTOMATION_FILE_PATH),
|
|
48
|
+
format: zod__default.enum(["cucumber", "testng", "junit", "qaf", "hpuft", "specflow"]).describe(SCHEMA_DESCRIPTIONS.AUTOMATION_FORMAT),
|
|
49
|
+
testCycleToReuse: zod__default.string().optional().describe(SCHEMA_DESCRIPTIONS.AUTOMATION_TEST_CYCLE_TO_REUSE),
|
|
50
|
+
environment: zod__default.string().optional().describe(SCHEMA_DESCRIPTIONS.AUTOMATION_ENVIRONMENT),
|
|
51
|
+
build: zod__default.string().optional().describe(SCHEMA_DESCRIPTIONS.AUTOMATION_BUILD),
|
|
52
|
+
isZip: zod__default.boolean().optional().default(false).describe(SCHEMA_DESCRIPTIONS.AUTOMATION_IS_ZIP),
|
|
53
|
+
attachFile: zod__default.boolean().optional().default(false).describe(SCHEMA_DESCRIPTIONS.AUTOMATION_ATTACH_FILE),
|
|
54
|
+
matchTestSteps: zod__default.boolean().optional().default(true).describe(SCHEMA_DESCRIPTIONS.AUTOMATION_MATCH_TEST_STEPS),
|
|
55
|
+
appendTestName: zod__default.boolean().optional().describe(SCHEMA_DESCRIPTIONS.AUTOMATION_APPEND_TEST_NAME),
|
|
56
|
+
fields: zod__default.object({
|
|
57
|
+
testCycle: TestCycleFields,
|
|
58
|
+
testCase: TestCaseFields,
|
|
59
|
+
testCaseExecution: TestCaseExecutionFields
|
|
60
|
+
}).optional().describe(SCHEMA_DESCRIPTIONS.AUTOMATION_FIELDS)
|
|
61
|
+
});
|
|
62
|
+
const UploadAutomationResultResponse = zod__default.object({
|
|
63
|
+
trackingId: zod__default.string(),
|
|
64
|
+
message: zod__default.string(),
|
|
65
|
+
filePath: zod__default.string(),
|
|
66
|
+
format: zod__default.enum(["cucumber", "testng", "junit", "qaf", "hpuft", "specflow"])
|
|
67
|
+
});
|
|
68
|
+
const GetAutomationHistoryBody = zod__default.object({
|
|
69
|
+
startAt: zod__default.number().int().min(0).optional().default(0).describe(SCHEMA_DESCRIPTIONS.AUTOMATION_HISTORY_START_AT),
|
|
70
|
+
maxResults: zod__default.number().int().min(1).max(100).optional().default(20).describe(SCHEMA_DESCRIPTIONS.AUTOMATION_HISTORY_MAX_RESULTS)
|
|
71
|
+
});
|
|
72
|
+
const AutomationHistorySummary = zod__default.object({
|
|
73
|
+
testCycle: zod__default.string().nullable().optional(),
|
|
74
|
+
testCasesCreated: zod__default.number().nullable().optional(),
|
|
75
|
+
testCaseVersionsCreated: zod__default.number().nullable().optional(),
|
|
76
|
+
testCaseVersionsReused: zod__default.number().nullable().optional(),
|
|
77
|
+
testStepsCreated: zod__default.number().nullable().optional(),
|
|
78
|
+
testCycleIssueKey: zod__default.string().nullable().optional(),
|
|
79
|
+
testCycleSummary: zod__default.string().nullable().optional()
|
|
80
|
+
});
|
|
81
|
+
const AutomationHistoryRecord = zod__default.object({
|
|
82
|
+
trackingId: zod__default.string().nullable().optional(),
|
|
83
|
+
fileName: zod__default.string().nullable().optional(),
|
|
84
|
+
format: zod__default.string().nullable().optional(),
|
|
85
|
+
processStatus: zod__default.string().nullable().optional(),
|
|
86
|
+
importStatus: zod__default.string().nullable().optional(),
|
|
87
|
+
startTime: zod__default.string().nullable().optional(),
|
|
88
|
+
endTime: zod__default.string().nullable().optional(),
|
|
89
|
+
fileSize: zod__default.number().nullable().optional(),
|
|
90
|
+
detailedMessage: zod__default.string().nullable().optional(),
|
|
91
|
+
extraAttributes: zod__default.record(zod__default.string(), zod__default.any()).nullable().optional(),
|
|
92
|
+
childFileSummaryResponses: zod__default.array(zod__default.any()).nullable().optional(),
|
|
93
|
+
summary: zod__default.array(AutomationHistorySummary).nullable().optional()
|
|
94
|
+
});
|
|
95
|
+
const GetAutomationHistoryResponse = zod__default.object({
|
|
96
|
+
startAt: zod__default.number().nullable().optional(),
|
|
97
|
+
maxResults: zod__default.number().nullable().optional(),
|
|
98
|
+
total: zod__default.number().nullable().optional(),
|
|
99
|
+
data: zod__default.array(AutomationHistoryRecord).nullable().optional()
|
|
100
|
+
});
|
|
101
|
+
export {
|
|
102
|
+
AutomationHistoryRecord,
|
|
103
|
+
GetAutomationHistoryBody,
|
|
104
|
+
GetAutomationHistoryResponse,
|
|
105
|
+
UploadAutomationResultBody,
|
|
106
|
+
UploadAutomationResultResponse
|
|
107
|
+
};
|