@dichovsky/testrail-api-client 1.0.0 → 2.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 +22 -0
- package/dist/cli/auth.d.ts +21 -0
- package/dist/cli/auth.js +16 -0
- package/dist/cli/body.d.ts +42 -0
- package/dist/cli/body.js +89 -0
- package/dist/cli/dispatch.d.ts +16 -0
- package/dist/cli/dispatch.js +87 -0
- package/dist/cli/handler-context.d.ts +43 -0
- package/dist/cli/handler-context.js +2 -0
- package/dist/cli/handlers/case-write.d.ts +4 -0
- package/dist/cli/handlers/case-write.js +26 -0
- package/dist/cli/handlers/case.d.ts +4 -0
- package/dist/cli/handlers/case.js +11 -0
- package/dist/cli/handlers/milestone.d.ts +4 -0
- package/dist/cli/handlers/milestone.js +15 -0
- package/dist/cli/handlers/project.d.ts +4 -0
- package/dist/cli/handlers/project.js +11 -0
- package/dist/cli/handlers/result-write.d.ts +4 -0
- package/dist/cli/handlers/result-write.js +40 -0
- package/dist/cli/handlers/result.d.ts +3 -0
- package/dist/cli/handlers/result.js +11 -0
- package/dist/cli/handlers/run-write.d.ts +10 -0
- package/dist/cli/handlers/run-write.js +29 -0
- package/dist/cli/handlers/run.d.ts +4 -0
- package/dist/cli/handlers/run.js +15 -0
- package/dist/cli/handlers/suite.d.ts +4 -0
- package/dist/cli/handlers/suite.js +10 -0
- package/dist/cli/handlers/user.d.ts +4 -0
- package/dist/cli/handlers/user.js +11 -0
- package/dist/cli/ids.d.ts +6 -0
- package/dist/cli/ids.js +20 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +198 -0
- package/dist/cli/install-skill.d.ts +35 -0
- package/dist/cli/install-skill.js +71 -0
- package/dist/cli/metadata.d.ts +37 -0
- package/dist/cli/metadata.js +151 -0
- package/dist/cli/output.d.ts +28 -0
- package/dist/cli/output.js +84 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +1 -266
- package/dist/client-core.d.ts +16 -7
- package/dist/client-core.js +153 -27
- package/dist/client.d.ts +274 -118
- package/dist/client.js +404 -463
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/errors.d.ts +11 -9
- package/dist/errors.js +12 -8
- package/dist/index.d.ts +4 -2
- package/dist/index.js +2 -1
- package/dist/modules/attachments.d.ts +19 -0
- package/dist/modules/attachments.js +64 -0
- package/dist/modules/cases.d.ts +13 -0
- package/dist/modules/cases.js +58 -0
- package/dist/modules/configurations.d.ts +14 -0
- package/dist/modules/configurations.js +37 -0
- package/dist/modules/datasets.d.ts +12 -0
- package/dist/modules/datasets.js +28 -0
- package/dist/modules/metadata.d.ts +14 -0
- package/dist/modules/metadata.js +31 -0
- package/dist/modules/milestones.d.ts +12 -0
- package/dist/modules/milestones.js +36 -0
- package/dist/modules/plans.d.ts +16 -0
- package/dist/modules/plans.js +59 -0
- package/dist/modules/projects.d.ts +36 -0
- package/dist/modules/projects.js +55 -0
- package/dist/modules/reports.d.ts +9 -0
- package/dist/modules/reports.js +16 -0
- package/dist/modules/results.d.ts +14 -0
- package/dist/modules/results.js +69 -0
- package/dist/modules/runs.d.ts +14 -0
- package/dist/modules/runs.js +57 -0
- package/dist/modules/sections.d.ts +16 -0
- package/dist/modules/sections.js +37 -0
- package/dist/modules/sharedSteps.d.ts +12 -0
- package/dist/modules/sharedSteps.js +28 -0
- package/dist/modules/suites.d.ts +37 -0
- package/dist/modules/suites.js +54 -0
- package/dist/modules/tests.d.ts +9 -0
- package/dist/modules/tests.js +25 -0
- package/dist/modules/users.d.ts +18 -0
- package/dist/modules/users.js +62 -0
- package/dist/modules/variables.d.ts +11 -0
- package/dist/modules/variables.js +24 -0
- package/dist/schemas.d.ts +544 -0
- package/dist/schemas.js +419 -0
- package/dist/types.d.ts +1 -55
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +4 -0
- package/package.json +23 -15
- package/skill/SKILL.md +395 -0
- package/src/cli/auth.ts +37 -0
- package/src/cli/body.ts +100 -0
- package/src/cli/dispatch.ts +91 -0
- package/src/cli/handler-context.ts +46 -0
- package/src/cli/handlers/case-write.ts +26 -0
- package/src/cli/handlers/case.ts +13 -0
- package/src/cli/handlers/milestone.ts +19 -0
- package/src/cli/handlers/project.ts +13 -0
- package/src/cli/handlers/result-write.ts +40 -0
- package/src/cli/handlers/result.ts +14 -0
- package/src/cli/handlers/run-write.ts +30 -0
- package/src/cli/handlers/run.ts +19 -0
- package/src/cli/handlers/suite.ts +12 -0
- package/src/cli/handlers/user.ts +13 -0
- package/src/cli/ids.ts +20 -0
- package/src/cli/index.ts +224 -0
- package/src/cli/install-skill.ts +89 -0
- package/src/cli/metadata.ts +194 -0
- package/src/cli/output.ts +96 -0
- package/src/cli.ts +1 -286
- package/src/client-core.ts +183 -67
- package/src/client.ts +414 -483
- package/src/constants.ts +1 -0
- package/src/errors.ts +18 -11
- package/src/index.ts +50 -8
- package/src/modules/attachments.ts +125 -0
- package/src/modules/cases.ts +78 -0
- package/src/modules/configurations.ts +68 -0
- package/src/modules/datasets.ts +44 -0
- package/src/modules/metadata.ts +63 -0
- package/src/modules/milestones.ts +54 -0
- package/src/modules/plans.ts +89 -0
- package/src/modules/projects.ts +67 -0
- package/src/modules/reports.ts +23 -0
- package/src/modules/results.ts +90 -0
- package/src/modules/runs.ts +70 -0
- package/src/modules/sections.ts +55 -0
- package/src/modules/sharedSteps.ts +44 -0
- package/src/modules/suites.ts +67 -0
- package/src/modules/tests.ts +28 -0
- package/src/modules/users.ts +87 -0
- package/src/modules/variables.ts +36 -0
- package/src/schemas.ts +551 -0
- package/src/types.ts +11 -60
- package/src/utils.ts +5 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { TestRailClientCore } from '../client-core.js';
|
|
2
|
+
import type { Project, AddProjectPayload, UpdateProjectPayload } from '../types.js';
|
|
3
|
+
import { ProjectSchema } from '../schemas.js';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
|
|
6
|
+
export class ProjectModule {
|
|
7
|
+
constructor(private readonly client: TestRailClientCore) {}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Get a project by ID.
|
|
11
|
+
* @throws {TestRailValidationError} When projectId is invalid
|
|
12
|
+
* @throws {TestRailApiError} When the API request fails
|
|
13
|
+
*/
|
|
14
|
+
async getProject(projectId: number): Promise<Project> {
|
|
15
|
+
this.client.validateId(projectId, 'projectId');
|
|
16
|
+
return this.client.parse(ProjectSchema, await this.client.request<unknown>('GET', `get_project/${projectId}`));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get all projects.
|
|
21
|
+
* @throws {TestRailValidationError} When limit or offset is invalid
|
|
22
|
+
* @throws {TestRailApiError} When the API request fails
|
|
23
|
+
*/
|
|
24
|
+
async getProjects(limit?: number, offset?: number): Promise<Project[]> {
|
|
25
|
+
this.client.validatePaginationParams(limit, offset);
|
|
26
|
+
const endpoint = this.client.buildEndpoint('get_projects', { limit, offset });
|
|
27
|
+
const raw = await this.client.request<unknown>('GET', endpoint);
|
|
28
|
+
return (
|
|
29
|
+
this.client.parse<{ projects?: Project[] }>(z.object({ projects: z.array(ProjectSchema).optional() }), raw)
|
|
30
|
+
.projects ?? []
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Add a new project.
|
|
36
|
+
* @throws {TestRailApiError} When the API request fails
|
|
37
|
+
*/
|
|
38
|
+
async addProject(payload: AddProjectPayload): Promise<Project> {
|
|
39
|
+
return this.client.parse<Project>(
|
|
40
|
+
ProjectSchema,
|
|
41
|
+
await this.client.request<unknown>('POST', 'add_project', payload),
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Update an existing project.
|
|
47
|
+
* @throws {TestRailValidationError} When projectId is invalid
|
|
48
|
+
* @throws {TestRailApiError} When the API request fails
|
|
49
|
+
*/
|
|
50
|
+
async updateProject(projectId: number, payload: UpdateProjectPayload): Promise<Project> {
|
|
51
|
+
this.client.validateId(projectId, 'projectId');
|
|
52
|
+
return this.client.parse<Project>(
|
|
53
|
+
ProjectSchema,
|
|
54
|
+
await this.client.request<unknown>('POST', `update_project/${projectId}`, payload),
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Delete a project.
|
|
60
|
+
* @throws {TestRailValidationError} When projectId is invalid
|
|
61
|
+
* @throws {TestRailApiError} When the API request fails
|
|
62
|
+
*/
|
|
63
|
+
async deleteProject(projectId: number): Promise<void> {
|
|
64
|
+
this.client.validateId(projectId, 'projectId');
|
|
65
|
+
await this.client.request<void>('POST', `delete_project/${projectId}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { TestRailClientCore } from '../client-core.js';
|
|
2
|
+
import type { Report, ReportResult } from '../types.js';
|
|
3
|
+
import { ReportSchema, ReportResultSchema } from '../schemas.js';
|
|
4
|
+
|
|
5
|
+
export class ReportModule {
|
|
6
|
+
constructor(private readonly client: TestRailClientCore) {}
|
|
7
|
+
|
|
8
|
+
async getReports(projectId: number): Promise<Report[]> {
|
|
9
|
+
this.client.validateId(projectId, 'projectId');
|
|
10
|
+
return this.client.parse<Report[]>(
|
|
11
|
+
ReportSchema.array(),
|
|
12
|
+
await this.client.request<unknown>('GET', `get_reports/${projectId}`),
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async runReport(reportTemplateId: number): Promise<ReportResult> {
|
|
17
|
+
this.client.validateId(reportTemplateId, 'reportTemplateId');
|
|
18
|
+
return this.client.parse<ReportResult>(
|
|
19
|
+
ReportResultSchema,
|
|
20
|
+
await this.client.request<unknown>('GET', `run_report/${reportTemplateId}`),
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { TestRailClientCore } from '../client-core.js';
|
|
2
|
+
import type { Result, GetResultsOptions } from '../types.js';
|
|
3
|
+
import type { AddResultPayload, AddResultsForCasesPayload } from '../schemas.js';
|
|
4
|
+
import { ResultSchema } from '../schemas.js';
|
|
5
|
+
import { serializeIdList } from '../utils.js';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
|
|
8
|
+
export class ResultModule {
|
|
9
|
+
constructor(private readonly client: TestRailClientCore) {}
|
|
10
|
+
|
|
11
|
+
async getResults(testId: number, options?: GetResultsOptions): Promise<Result[]> {
|
|
12
|
+
this.client.validateId(testId, 'testId');
|
|
13
|
+
this.client.validatePaginationParams(options?.limit, options?.offset);
|
|
14
|
+
const endpoint = this.client.buildEndpoint(`get_results/${testId}`, {
|
|
15
|
+
created_after: options?.created_after,
|
|
16
|
+
created_before: options?.created_before,
|
|
17
|
+
created_by: serializeIdList(options?.created_by),
|
|
18
|
+
status_id: serializeIdList(options?.status_id),
|
|
19
|
+
limit: options?.limit,
|
|
20
|
+
offset: options?.offset,
|
|
21
|
+
});
|
|
22
|
+
const raw = await this.client.request<unknown>('GET', endpoint);
|
|
23
|
+
return (
|
|
24
|
+
this.client.parse<{ results?: Result[] }>(z.object({ results: z.array(ResultSchema).optional() }), raw)
|
|
25
|
+
.results ?? []
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async getResultsForCase(runId: number, caseId: number, options?: GetResultsOptions): Promise<Result[]> {
|
|
30
|
+
this.client.validateId(runId, 'runId');
|
|
31
|
+
this.client.validateId(caseId, 'caseId');
|
|
32
|
+
this.client.validatePaginationParams(options?.limit, options?.offset);
|
|
33
|
+
const endpoint = this.client.buildEndpoint(`get_results_for_case/${runId}/${caseId}`, {
|
|
34
|
+
created_after: options?.created_after,
|
|
35
|
+
created_before: options?.created_before,
|
|
36
|
+
created_by: serializeIdList(options?.created_by),
|
|
37
|
+
status_id: serializeIdList(options?.status_id),
|
|
38
|
+
limit: options?.limit,
|
|
39
|
+
offset: options?.offset,
|
|
40
|
+
});
|
|
41
|
+
const raw = await this.client.request<unknown>('GET', endpoint);
|
|
42
|
+
return (
|
|
43
|
+
this.client.parse<{ results?: Result[] }>(z.object({ results: z.array(ResultSchema).optional() }), raw)
|
|
44
|
+
.results ?? []
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async getResultsForRun(runId: number, options?: GetResultsOptions): Promise<Result[]> {
|
|
49
|
+
this.client.validateId(runId, 'runId');
|
|
50
|
+
this.client.validatePaginationParams(options?.limit, options?.offset);
|
|
51
|
+
const endpoint = this.client.buildEndpoint(`get_results_for_run/${runId}`, {
|
|
52
|
+
created_after: options?.created_after,
|
|
53
|
+
created_before: options?.created_before,
|
|
54
|
+
created_by: serializeIdList(options?.created_by),
|
|
55
|
+
status_id: serializeIdList(options?.status_id),
|
|
56
|
+
limit: options?.limit,
|
|
57
|
+
offset: options?.offset,
|
|
58
|
+
});
|
|
59
|
+
const raw = await this.client.request<unknown>('GET', endpoint);
|
|
60
|
+
return (
|
|
61
|
+
this.client.parse<{ results?: Result[] }>(z.object({ results: z.array(ResultSchema).optional() }), raw)
|
|
62
|
+
.results ?? []
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async addResult(testId: number, payload: AddResultPayload): Promise<Result> {
|
|
67
|
+
this.client.validateId(testId, 'testId');
|
|
68
|
+
return this.client.parse<Result>(
|
|
69
|
+
ResultSchema,
|
|
70
|
+
await this.client.request<unknown>('POST', `add_result/${testId}`, payload),
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async addResultForCase(runId: number, caseId: number, payload: AddResultPayload): Promise<Result> {
|
|
75
|
+
this.client.validateId(runId, 'runId');
|
|
76
|
+
this.client.validateId(caseId, 'caseId');
|
|
77
|
+
return this.client.parse<Result>(
|
|
78
|
+
ResultSchema,
|
|
79
|
+
await this.client.request<unknown>('POST', `add_result_for_case/${runId}/${caseId}`, payload),
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async addResultsForCases(runId: number, payload: AddResultsForCasesPayload): Promise<Result[]> {
|
|
84
|
+
this.client.validateId(runId, 'runId');
|
|
85
|
+
return this.client.parse<Result[]>(
|
|
86
|
+
z.array(ResultSchema),
|
|
87
|
+
await this.client.request<unknown>('POST', `add_results_for_cases/${runId}`, payload),
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { TestRailClientCore } from '../client-core.js';
|
|
2
|
+
import type { Run, GetRunsOptions } from '../types.js';
|
|
3
|
+
import type { AddRunPayload, UpdateRunPayload } from '../schemas.js';
|
|
4
|
+
import { RunSchema } from '../schemas.js';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
|
|
7
|
+
export class RunModule {
|
|
8
|
+
constructor(private readonly client: TestRailClientCore) {}
|
|
9
|
+
|
|
10
|
+
async getRun(runId: number): Promise<Run> {
|
|
11
|
+
this.client.validateId(runId, 'runId');
|
|
12
|
+
return this.client.parse<Run>(RunSchema, await this.client.request<unknown>('GET', `get_run/${runId}`));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async getRuns(projectId: number, options?: GetRunsOptions): Promise<Run[]> {
|
|
16
|
+
this.client.validateId(projectId, 'projectId');
|
|
17
|
+
const { createdAfter, createdBefore, createdBy, isCompleted, milestoneId, refsFilter, suiteId, limit, offset } =
|
|
18
|
+
options ?? {};
|
|
19
|
+
this.client.validatePaginationParams(limit, offset);
|
|
20
|
+
if (milestoneId !== undefined) {
|
|
21
|
+
this.client.validateId(milestoneId, 'milestoneId');
|
|
22
|
+
}
|
|
23
|
+
if (suiteId !== undefined) {
|
|
24
|
+
this.client.validateId(suiteId, 'suiteId');
|
|
25
|
+
}
|
|
26
|
+
if (createdBy !== undefined) {
|
|
27
|
+
createdBy.forEach((userId) => this.client.validateId(userId, 'createdBy'));
|
|
28
|
+
}
|
|
29
|
+
const createdByFilter = createdBy && createdBy.length > 0 ? createdBy.join(',') : undefined;
|
|
30
|
+
const endpoint = this.client.buildEndpoint(`get_runs/${projectId}`, {
|
|
31
|
+
created_after: createdAfter,
|
|
32
|
+
created_before: createdBefore,
|
|
33
|
+
created_by: createdByFilter,
|
|
34
|
+
is_completed: isCompleted !== undefined ? (isCompleted ? 1 : 0) : undefined,
|
|
35
|
+
milestone_id: milestoneId,
|
|
36
|
+
refs_filter: refsFilter,
|
|
37
|
+
suite_id: suiteId,
|
|
38
|
+
limit,
|
|
39
|
+
offset,
|
|
40
|
+
});
|
|
41
|
+
const raw = await this.client.request<unknown>('GET', endpoint);
|
|
42
|
+
return this.client.parse<{ runs?: Run[] }>(z.object({ runs: z.array(RunSchema).optional() }), raw).runs ?? [];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async addRun(projectId: number, payload: AddRunPayload): Promise<Run> {
|
|
46
|
+
this.client.validateId(projectId, 'projectId');
|
|
47
|
+
return this.client.parse<Run>(
|
|
48
|
+
RunSchema,
|
|
49
|
+
await this.client.request<unknown>('POST', `add_run/${projectId}`, payload),
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async updateRun(runId: number, payload: UpdateRunPayload): Promise<Run> {
|
|
54
|
+
this.client.validateId(runId, 'runId');
|
|
55
|
+
return this.client.parse<Run>(
|
|
56
|
+
RunSchema,
|
|
57
|
+
await this.client.request<unknown>('POST', `update_run/${runId}`, payload),
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async closeRun(runId: number): Promise<Run> {
|
|
62
|
+
this.client.validateId(runId, 'runId');
|
|
63
|
+
return this.client.parse<Run>(RunSchema, await this.client.request<unknown>('POST', `close_run/${runId}`));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async deleteRun(runId: number): Promise<void> {
|
|
67
|
+
this.client.validateId(runId, 'runId');
|
|
68
|
+
await this.client.request<void>('POST', `delete_run/${runId}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { TestRailClientCore } from '../client-core.js';
|
|
2
|
+
import type { Section, AddSectionPayload, UpdateSectionPayload } from '../types.js';
|
|
3
|
+
import { SectionSchema } from '../schemas.js';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
|
|
6
|
+
export class SectionModule {
|
|
7
|
+
constructor(private readonly client: TestRailClientCore) {}
|
|
8
|
+
|
|
9
|
+
async getSection(sectionId: number): Promise<Section> {
|
|
10
|
+
this.client.validateId(sectionId, 'sectionId');
|
|
11
|
+
return this.client.parse<Section>(
|
|
12
|
+
SectionSchema,
|
|
13
|
+
await this.client.request<unknown>('GET', `get_section/${sectionId}`),
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async getSections(
|
|
18
|
+
projectId: number,
|
|
19
|
+
options?: { suiteId?: number; limit?: number; offset?: number },
|
|
20
|
+
): Promise<Section[]> {
|
|
21
|
+
this.client.validateId(projectId, 'projectId');
|
|
22
|
+
const { suiteId, limit, offset } = options ?? {};
|
|
23
|
+
if (suiteId !== undefined) {
|
|
24
|
+
this.client.validateId(suiteId, 'suiteId');
|
|
25
|
+
}
|
|
26
|
+
this.client.validatePaginationParams(limit, offset);
|
|
27
|
+
const endpoint = this.client.buildEndpoint(`get_sections/${projectId}`, { suite_id: suiteId, limit, offset });
|
|
28
|
+
const raw = await this.client.request<unknown>('GET', endpoint);
|
|
29
|
+
return (
|
|
30
|
+
this.client.parse<{ sections?: Section[] }>(z.object({ sections: z.array(SectionSchema).optional() }), raw)
|
|
31
|
+
.sections ?? []
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async addSection(projectId: number, payload: AddSectionPayload): Promise<Section> {
|
|
36
|
+
this.client.validateId(projectId, 'projectId');
|
|
37
|
+
return this.client.parse<Section>(
|
|
38
|
+
SectionSchema,
|
|
39
|
+
await this.client.request<unknown>('POST', `add_section/${projectId}`, payload),
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async updateSection(sectionId: number, payload: UpdateSectionPayload): Promise<Section> {
|
|
44
|
+
this.client.validateId(sectionId, 'sectionId');
|
|
45
|
+
return this.client.parse<Section>(
|
|
46
|
+
SectionSchema,
|
|
47
|
+
await this.client.request<unknown>('POST', `update_section/${sectionId}`, payload),
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async deleteSection(sectionId: number): Promise<void> {
|
|
52
|
+
this.client.validateId(sectionId, 'sectionId');
|
|
53
|
+
await this.client.request<void>('POST', `delete_section/${sectionId}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { TestRailClientCore } from '../client-core.js';
|
|
2
|
+
import type { SharedStep, AddSharedStepPayload, UpdateSharedStepPayload } from '../types.js';
|
|
3
|
+
import { SharedStepSchema } from '../schemas.js';
|
|
4
|
+
|
|
5
|
+
export class SharedStepModule {
|
|
6
|
+
constructor(private readonly client: TestRailClientCore) {}
|
|
7
|
+
|
|
8
|
+
async getSharedStep(sharedStepId: number): Promise<SharedStep> {
|
|
9
|
+
this.client.validateId(sharedStepId, 'sharedStepId');
|
|
10
|
+
return this.client.parse<SharedStep>(
|
|
11
|
+
SharedStepSchema,
|
|
12
|
+
await this.client.request<unknown>('GET', `get_shared_step/${sharedStepId}`),
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async getSharedSteps(projectId: number): Promise<SharedStep[]> {
|
|
17
|
+
this.client.validateId(projectId, 'projectId');
|
|
18
|
+
return this.client.parse<SharedStep[]>(
|
|
19
|
+
SharedStepSchema.array(),
|
|
20
|
+
await this.client.request<unknown>('GET', `get_shared_steps/${projectId}`),
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async addSharedStep(projectId: number, payload: AddSharedStepPayload): Promise<SharedStep> {
|
|
25
|
+
this.client.validateId(projectId, 'projectId');
|
|
26
|
+
return this.client.parse<SharedStep>(
|
|
27
|
+
SharedStepSchema,
|
|
28
|
+
await this.client.request<unknown>('POST', `add_shared_step/${projectId}`, payload),
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async updateSharedStep(sharedStepId: number, payload: UpdateSharedStepPayload): Promise<SharedStep> {
|
|
33
|
+
this.client.validateId(sharedStepId, 'sharedStepId');
|
|
34
|
+
return this.client.parse<SharedStep>(
|
|
35
|
+
SharedStepSchema,
|
|
36
|
+
await this.client.request<unknown>('POST', `update_shared_step/${sharedStepId}`, payload),
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async deleteSharedStep(sharedStepId: number): Promise<void> {
|
|
41
|
+
this.client.validateId(sharedStepId, 'sharedStepId');
|
|
42
|
+
await this.client.request<void>('POST', `delete_shared_step/${sharedStepId}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { TestRailClientCore } from '../client-core.js';
|
|
2
|
+
import type { Suite, AddSuitePayload, UpdateSuitePayload } from '../types.js';
|
|
3
|
+
import { SuiteSchema } from '../schemas.js';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
|
|
6
|
+
export class SuiteModule {
|
|
7
|
+
constructor(private readonly client: TestRailClientCore) {}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Get a suite by ID.
|
|
11
|
+
* @throws {TestRailValidationError} When suiteId is invalid
|
|
12
|
+
* @throws {TestRailApiError} When the API request fails
|
|
13
|
+
*/
|
|
14
|
+
async getSuite(suiteId: number): Promise<Suite> {
|
|
15
|
+
this.client.validateId(suiteId, 'suiteId');
|
|
16
|
+
return this.client.parse<Suite>(SuiteSchema, await this.client.request<unknown>('GET', `get_suite/${suiteId}`));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get all suites for a project.
|
|
21
|
+
* @throws {TestRailValidationError} When projectId is invalid
|
|
22
|
+
* @throws {TestRailApiError} When the API request fails
|
|
23
|
+
*/
|
|
24
|
+
async getSuites(projectId: number): Promise<Suite[]> {
|
|
25
|
+
this.client.validateId(projectId, 'projectId');
|
|
26
|
+
return this.client.parse<Suite[]>(
|
|
27
|
+
z.array(SuiteSchema),
|
|
28
|
+
await this.client.request<unknown>('GET', `get_suites/${projectId}`),
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Add a suite to a project.
|
|
34
|
+
* @throws {TestRailValidationError} When projectId is invalid
|
|
35
|
+
* @throws {TestRailApiError} When the API request fails
|
|
36
|
+
*/
|
|
37
|
+
async addSuite(projectId: number, payload: AddSuitePayload): Promise<Suite> {
|
|
38
|
+
this.client.validateId(projectId, 'projectId');
|
|
39
|
+
return this.client.parse<Suite>(
|
|
40
|
+
SuiteSchema,
|
|
41
|
+
await this.client.request<unknown>('POST', `add_suite/${projectId}`, payload),
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Update a suite.
|
|
47
|
+
* @throws {TestRailValidationError} When suiteId is invalid
|
|
48
|
+
* @throws {TestRailApiError} When the API request fails
|
|
49
|
+
*/
|
|
50
|
+
async updateSuite(suiteId: number, payload: UpdateSuitePayload): Promise<Suite> {
|
|
51
|
+
this.client.validateId(suiteId, 'suiteId');
|
|
52
|
+
return this.client.parse<Suite>(
|
|
53
|
+
SuiteSchema,
|
|
54
|
+
await this.client.request<unknown>('POST', `update_suite/${suiteId}`, payload),
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Delete a suite.
|
|
60
|
+
* @throws {TestRailValidationError} When suiteId is invalid
|
|
61
|
+
* @throws {TestRailApiError} When the API request fails
|
|
62
|
+
*/
|
|
63
|
+
async deleteSuite(suiteId: number): Promise<void> {
|
|
64
|
+
this.client.validateId(suiteId, 'suiteId');
|
|
65
|
+
await this.client.request<void>('POST', `delete_suite/${suiteId}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { TestRailClientCore } from '../client-core.js';
|
|
2
|
+
import type { Test, GetTestsOptions } from '../types.js';
|
|
3
|
+
import { TestSchema } from '../schemas.js';
|
|
4
|
+
import { serializeIdList } from '../utils.js';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
|
|
7
|
+
export class TestModule {
|
|
8
|
+
constructor(private readonly client: TestRailClientCore) {}
|
|
9
|
+
|
|
10
|
+
async getTest(testId: number): Promise<Test> {
|
|
11
|
+
this.client.validateId(testId, 'testId');
|
|
12
|
+
return this.client.parse<Test>(TestSchema, await this.client.request<unknown>('GET', `get_test/${testId}`));
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async getTests(runId: number, options?: GetTestsOptions): Promise<Test[]> {
|
|
16
|
+
this.client.validateId(runId, 'runId');
|
|
17
|
+
this.client.validatePaginationParams(options?.limit, options?.offset);
|
|
18
|
+
const endpoint = this.client.buildEndpoint(`get_tests/${runId}`, {
|
|
19
|
+
status_id: serializeIdList(options?.status_id),
|
|
20
|
+
limit: options?.limit,
|
|
21
|
+
offset: options?.offset,
|
|
22
|
+
});
|
|
23
|
+
const raw = await this.client.request<unknown>('GET', endpoint);
|
|
24
|
+
return (
|
|
25
|
+
this.client.parse<{ tests?: Test[] }>(z.object({ tests: z.array(TestSchema).optional() }), raw).tests ?? []
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { TestRailValidationError } from '../errors.js';
|
|
3
|
+
import { UserSchema, GroupSchema } from '../schemas.js';
|
|
4
|
+
import { TestRailClientCore } from '../client-core.js';
|
|
5
|
+
import type { AddGroupPayload, AddUserPayload, Group, UpdateGroupPayload, UpdateUserPayload, User } from '../types.js';
|
|
6
|
+
|
|
7
|
+
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
8
|
+
|
|
9
|
+
export class UsersModule {
|
|
10
|
+
constructor(private readonly client: TestRailClientCore) {}
|
|
11
|
+
|
|
12
|
+
async getUser(userId: number): Promise<User> {
|
|
13
|
+
this.client.validateId(userId, 'userId');
|
|
14
|
+
return this.client.parse<User>(UserSchema, await this.client.request<unknown>('GET', `get_user/${userId}`));
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async getUserByEmail(email: string): Promise<User> {
|
|
18
|
+
if (!EMAIL_REGEX.test(email)) {
|
|
19
|
+
throw new TestRailValidationError('Invalid email format');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const endpoint = this.client.buildEndpoint('get_user_by_email', { email });
|
|
23
|
+
return this.client.parse<User>(UserSchema, await this.client.request<unknown>('GET', endpoint));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async getUsers(limit?: number, offset?: number, projectId?: number): Promise<User[]> {
|
|
27
|
+
this.client.validatePaginationParams(limit, offset);
|
|
28
|
+
if (projectId !== undefined) {
|
|
29
|
+
this.client.validateId(projectId, 'projectId');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const endpoint = this.client.buildEndpoint(projectId !== undefined ? `get_users/${projectId}` : 'get_users', {
|
|
33
|
+
limit,
|
|
34
|
+
offset,
|
|
35
|
+
});
|
|
36
|
+
const raw = await this.client.request<unknown>('GET', endpoint);
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
this.client.parse<{ users?: User[] }>(z.object({ users: z.array(UserSchema).optional() }), raw).users ?? []
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async getCurrentUser(): Promise<User> {
|
|
44
|
+
return this.client.parse<User>(UserSchema, await this.client.request<unknown>('GET', 'get_current_user'));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async addUser(payload: AddUserPayload): Promise<User> {
|
|
48
|
+
return this.client.parse<User>(UserSchema, await this.client.request<unknown>('POST', 'add_user', payload));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async updateUser(userId: number, payload: UpdateUserPayload): Promise<User> {
|
|
52
|
+
this.client.validateId(userId, 'userId');
|
|
53
|
+
return this.client.parse<User>(
|
|
54
|
+
UserSchema,
|
|
55
|
+
await this.client.request<unknown>('POST', `update_user/${userId}`, payload),
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async getGroup(groupId: number): Promise<Group> {
|
|
60
|
+
this.client.validateId(groupId, 'groupId');
|
|
61
|
+
return this.client.parse<Group>(GroupSchema, await this.client.request<unknown>('GET', `get_group/${groupId}`));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async getGroups(): Promise<Group[]> {
|
|
65
|
+
return this.client.parse<Group[]>(
|
|
66
|
+
z.array(GroupSchema),
|
|
67
|
+
await this.client.request<unknown>('GET', 'get_groups'),
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async addGroup(payload: AddGroupPayload): Promise<Group> {
|
|
72
|
+
return this.client.parse<Group>(GroupSchema, await this.client.request<unknown>('POST', 'add_group', payload));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async updateGroup(groupId: number, payload: UpdateGroupPayload): Promise<Group> {
|
|
76
|
+
this.client.validateId(groupId, 'groupId');
|
|
77
|
+
return this.client.parse<Group>(
|
|
78
|
+
GroupSchema,
|
|
79
|
+
await this.client.request<unknown>('POST', `update_group/${groupId}`, payload),
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async deleteGroup(groupId: number): Promise<void> {
|
|
84
|
+
this.client.validateId(groupId, 'groupId');
|
|
85
|
+
await this.client.request<void>('POST', `delete_group/${groupId}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { TestRailClientCore } from '../client-core.js';
|
|
2
|
+
import type { Variable, AddVariablePayload, UpdateVariablePayload } from '../types.js';
|
|
3
|
+
import { VariableSchema } from '../schemas.js';
|
|
4
|
+
|
|
5
|
+
export class VariableModule {
|
|
6
|
+
constructor(private readonly client: TestRailClientCore) {}
|
|
7
|
+
|
|
8
|
+
async getVariables(projectId: number): Promise<Variable[]> {
|
|
9
|
+
this.client.validateId(projectId, 'projectId');
|
|
10
|
+
return this.client.parse<Variable[]>(
|
|
11
|
+
VariableSchema.array(),
|
|
12
|
+
await this.client.request<unknown>('GET', `get_variables/${projectId}`),
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async addVariable(projectId: number, payload: AddVariablePayload): Promise<Variable> {
|
|
17
|
+
this.client.validateId(projectId, 'projectId');
|
|
18
|
+
return this.client.parse<Variable>(
|
|
19
|
+
VariableSchema,
|
|
20
|
+
await this.client.request<unknown>('POST', `add_variable/${projectId}`, payload),
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async updateVariable(variableId: number, payload: UpdateVariablePayload): Promise<Variable> {
|
|
25
|
+
this.client.validateId(variableId, 'variableId');
|
|
26
|
+
return this.client.parse<Variable>(
|
|
27
|
+
VariableSchema,
|
|
28
|
+
await this.client.request<unknown>('POST', `update_variable/${variableId}`, payload),
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async deleteVariable(variableId: number): Promise<void> {
|
|
33
|
+
this.client.validateId(variableId, 'variableId');
|
|
34
|
+
await this.client.request<void>('POST', `delete_variable/${variableId}`);
|
|
35
|
+
}
|
|
36
|
+
}
|