@browserstack/mcp-server 1.1.9 → 1.2.1
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 +4 -1
- package/dist/config.d.ts +13 -0
- package/dist/config.js +4 -6
- package/dist/index.d.ts +4 -0
- package/dist/index.js +21 -31
- package/dist/lib/api.d.ts +2 -0
- package/dist/lib/api.js +10 -5
- package/dist/lib/apiClient.d.ts +31 -0
- package/dist/lib/apiClient.js +108 -0
- package/dist/lib/constants.d.ts +17 -0
- package/dist/lib/device-cache.d.ts +9 -0
- package/dist/lib/device-cache.js +3 -3
- package/dist/lib/error.d.ts +7 -0
- package/dist/lib/fuzzy.d.ts +1 -0
- package/dist/lib/get-auth.d.ts +2 -0
- package/dist/lib/get-auth.js +8 -0
- package/dist/lib/inmemory-store.d.ts +1 -0
- package/dist/lib/instrumentation.d.ts +4 -0
- package/dist/lib/instrumentation.js +8 -7
- package/dist/lib/local.d.ts +3 -0
- package/dist/lib/local.js +3 -3
- package/dist/lib/types.d.ts +4 -0
- package/dist/lib/types.js +1 -0
- package/dist/lib/utils.d.ts +4 -0
- package/dist/lib/version-resolver.d.ts +6 -0
- package/dist/logger.d.ts +3 -0
- package/dist/logger.js +20 -4
- package/dist/oninitialized.d.ts +2 -0
- package/dist/oninitialized.js +2 -7
- package/dist/server-factory.d.ts +25 -0
- package/dist/server-factory.js +70 -0
- package/dist/tools/accessibility.d.ts +3 -0
- package/dist/tools/accessibility.js +21 -12
- package/dist/tools/accessiblity-utils/accessibility-rag.d.ts +12 -0
- package/dist/tools/accessiblity-utils/accessibility-rag.js +22 -12
- package/dist/tools/accessiblity-utils/report-fetcher.d.ts +8 -0
- package/dist/tools/accessiblity-utils/report-fetcher.js +26 -16
- package/dist/tools/accessiblity-utils/report-parser.d.ts +23 -0
- package/dist/tools/accessiblity-utils/report-parser.js +3 -3
- package/dist/tools/accessiblity-utils/scanner.d.ts +25 -0
- package/dist/tools/accessiblity-utils/scanner.js +43 -24
- package/dist/tools/appautomate-utils/appautomate.d.ts +42 -0
- package/dist/tools/appautomate-utils/appautomate.js +63 -38
- package/dist/tools/appautomate-utils/types.d.ts +5 -0
- package/dist/tools/appautomate.d.ts +3 -0
- package/dist/tools/appautomate.js +24 -21
- package/dist/tools/applive-utils/device-search.d.ts +6 -0
- package/dist/tools/applive-utils/start-session.d.ts +15 -0
- package/dist/tools/applive-utils/start-session.js +11 -4
- package/dist/tools/applive-utils/types.d.ts +7 -0
- package/dist/tools/applive-utils/upload-app.d.ts +5 -0
- package/dist/tools/applive-utils/upload-app.js +8 -12
- package/dist/tools/applive-utils/version-utils.d.ts +4 -0
- package/dist/tools/applive.d.ts +13 -0
- package/dist/tools/applive.js +9 -7
- package/dist/tools/automate-utils/fetch-screenshots.d.ts +6 -0
- package/dist/tools/automate-utils/fetch-screenshots.js +16 -12
- package/dist/tools/automate.d.ts +9 -0
- package/dist/tools/automate.js +9 -7
- package/dist/tools/bstack-sdk.d.ts +17 -0
- package/dist/tools/bstack-sdk.js +15 -8
- package/dist/tools/failurelogs-utils/app-automate.d.ts +7 -0
- package/dist/tools/failurelogs-utils/app-automate.js +29 -11
- package/dist/tools/failurelogs-utils/automate.d.ts +6 -0
- package/dist/tools/failurelogs-utils/automate.js +27 -12
- package/dist/tools/failurelogs-utils/utils.d.ts +30 -0
- package/dist/tools/getFailureLogs.d.ts +14 -0
- package/dist/tools/getFailureLogs.js +15 -16
- package/dist/tools/live-utils/desktop-filter.d.ts +2 -0
- package/dist/tools/live-utils/mobile-filter.d.ts +2 -0
- package/dist/tools/live-utils/start-session.d.ts +6 -0
- package/dist/tools/live-utils/start-session.js +18 -5
- package/dist/tools/live-utils/types.d.ts +33 -0
- package/dist/tools/live.d.ts +3 -0
- package/dist/tools/live.js +28 -16
- package/dist/tools/observability.d.ts +5 -0
- package/dist/tools/observability.js +14 -11
- package/dist/tools/sdk-utils/commands.d.ts +3 -0
- package/dist/tools/sdk-utils/commands.js +5 -4
- package/dist/tools/sdk-utils/constants.d.ts +2 -0
- package/dist/tools/sdk-utils/constants.js +82 -21
- package/dist/tools/sdk-utils/instructions.d.ts +6 -0
- package/dist/tools/sdk-utils/instructions.js +8 -6
- package/dist/tools/sdk-utils/percy/constants.d.ts +3 -0
- package/dist/tools/sdk-utils/percy/constants.js +1 -0
- package/dist/tools/sdk-utils/percy/instructions.d.ts +10 -0
- package/dist/tools/sdk-utils/percy/types.d.ts +5 -0
- package/dist/tools/sdk-utils/types.d.ts +39 -0
- package/dist/tools/sdk-utils/types.js +1 -0
- package/dist/tools/selfheal-utils/selfheal.d.ts +11 -0
- package/dist/tools/selfheal-utils/selfheal.js +10 -6
- package/dist/tools/selfheal.d.ts +7 -0
- package/dist/tools/selfheal.js +9 -7
- package/dist/tools/testmanagement-utils/TCG-utils/api.d.ts +34 -0
- package/dist/tools/testmanagement-utils/TCG-utils/api.js +57 -44
- package/dist/tools/testmanagement-utils/TCG-utils/config.d.ts +5 -0
- package/dist/tools/testmanagement-utils/TCG-utils/helpers.d.ts +13 -0
- package/dist/tools/testmanagement-utils/TCG-utils/helpers.js +2 -1
- package/dist/tools/testmanagement-utils/TCG-utils/types.d.ts +26 -0
- package/dist/tools/testmanagement-utils/add-test-result.d.ts +42 -0
- package/dist/tools/testmanagement-utils/add-test-result.js +23 -10
- package/dist/tools/testmanagement-utils/create-lca-steps.d.ts +100 -0
- package/dist/tools/testmanagement-utils/create-lca-steps.js +64 -55
- package/dist/tools/testmanagement-utils/create-project-folder.d.ts +31 -0
- package/dist/tools/testmanagement-utils/create-project-folder.js +31 -21
- package/dist/tools/testmanagement-utils/create-testcase.d.ts +122 -0
- package/dist/tools/testmanagement-utils/create-testcase.js +13 -10
- package/dist/tools/testmanagement-utils/create-testrun.d.ts +82 -0
- package/dist/tools/testmanagement-utils/create-testrun.js +11 -8
- package/dist/tools/testmanagement-utils/list-testcases.d.ts +30 -0
- package/dist/tools/testmanagement-utils/list-testcases.js +9 -7
- package/dist/tools/testmanagement-utils/list-testruns.d.ts +22 -0
- package/dist/tools/testmanagement-utils/list-testruns.js +9 -7
- package/dist/tools/testmanagement-utils/poll-lca-status.d.ts +11 -0
- package/dist/tools/testmanagement-utils/poll-lca-status.js +12 -8
- package/dist/tools/testmanagement-utils/testcase-from-file.d.ts +4 -0
- package/dist/tools/testmanagement-utils/testcase-from-file.js +6 -6
- package/dist/tools/testmanagement-utils/update-testrun.d.ts +40 -0
- package/dist/tools/testmanagement-utils/update-testrun.js +11 -7
- package/dist/tools/testmanagement-utils/upload-file.d.ts +20 -0
- package/dist/tools/testmanagement-utils/upload-file.js +8 -6
- package/dist/tools/testmanagement.d.ts +60 -0
- package/dist/tools/testmanagement.js +53 -53
- package/package.json +1 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
import { BrowserStackConfig } from "../../lib/types.js";
|
|
4
|
+
export declare const CreateProjFoldSchema: z.ZodObject<{
|
|
5
|
+
project_name: z.ZodOptional<z.ZodString>;
|
|
6
|
+
project_description: z.ZodOptional<z.ZodString>;
|
|
7
|
+
project_identifier: z.ZodOptional<z.ZodString>;
|
|
8
|
+
folder_name: z.ZodOptional<z.ZodString>;
|
|
9
|
+
folder_description: z.ZodOptional<z.ZodString>;
|
|
10
|
+
parent_id: z.ZodOptional<z.ZodNumber>;
|
|
11
|
+
}, "strip", z.ZodTypeAny, {
|
|
12
|
+
project_name?: string | undefined;
|
|
13
|
+
project_description?: string | undefined;
|
|
14
|
+
project_identifier?: string | undefined;
|
|
15
|
+
folder_name?: string | undefined;
|
|
16
|
+
folder_description?: string | undefined;
|
|
17
|
+
parent_id?: number | undefined;
|
|
18
|
+
}, {
|
|
19
|
+
project_name?: string | undefined;
|
|
20
|
+
project_description?: string | undefined;
|
|
21
|
+
project_identifier?: string | undefined;
|
|
22
|
+
folder_name?: string | undefined;
|
|
23
|
+
folder_description?: string | undefined;
|
|
24
|
+
parent_id?: number | undefined;
|
|
25
|
+
}>;
|
|
26
|
+
type CreateProjFoldArgs = z.infer<typeof CreateProjFoldSchema>;
|
|
27
|
+
/**
|
|
28
|
+
* Creates a project and/or folder in BrowserStack Test Management.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createProjectOrFolder(args: CreateProjFoldArgs, config: BrowserStackConfig): Promise<CallToolResult>;
|
|
31
|
+
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import config from "../../config.js";
|
|
1
|
+
import { apiClient } from "../../lib/apiClient.js";
|
|
3
2
|
import { z } from "zod";
|
|
4
|
-
import { formatAxiosError } from "../../lib/error.js";
|
|
3
|
+
import { formatAxiosError } from "../../lib/error.js";
|
|
5
4
|
import { projectIdentifierToId } from "../testmanagement-utils/TCG-utils/api.js";
|
|
5
|
+
import { getBrowserStackAuth } from "../../lib/get-auth.js";
|
|
6
6
|
// Schema for combined project/folder creation
|
|
7
7
|
export const CreateProjFoldSchema = z.object({
|
|
8
8
|
project_name: z
|
|
@@ -30,21 +30,29 @@ export const CreateProjFoldSchema = z.object({
|
|
|
30
30
|
/**
|
|
31
31
|
* Creates a project and/or folder in BrowserStack Test Management.
|
|
32
32
|
*/
|
|
33
|
-
export async function createProjectOrFolder(args) {
|
|
33
|
+
export async function createProjectOrFolder(args, config) {
|
|
34
34
|
const { project_name, project_description, project_identifier, folder_name, folder_description, parent_id, } = CreateProjFoldSchema.parse(args);
|
|
35
35
|
if (!project_name && !project_identifier && !folder_name) {
|
|
36
36
|
throw new Error("Provide project_name (to create project), or project_identifier and folder_name (to create folder).");
|
|
37
37
|
}
|
|
38
|
+
const authString = getBrowserStackAuth(config);
|
|
39
|
+
const [username, password] = authString.split(":");
|
|
38
40
|
let projId = project_identifier;
|
|
39
41
|
// Step 1: Create project if project_name provided
|
|
40
42
|
if (project_name) {
|
|
41
43
|
try {
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
const authString = getBrowserStackAuth(config);
|
|
45
|
+
const [username, password] = authString.split(":");
|
|
46
|
+
const res = await apiClient.post({
|
|
47
|
+
url: "https://test-management.browserstack.com/api/v2/projects",
|
|
48
|
+
headers: {
|
|
49
|
+
"Content-Type": "application/json",
|
|
50
|
+
Authorization: "Basic " +
|
|
51
|
+
Buffer.from(`${username}:${password}`).toString("base64"),
|
|
52
|
+
},
|
|
53
|
+
body: {
|
|
54
|
+
project: { name: project_name, description: project_description },
|
|
46
55
|
},
|
|
47
|
-
headers: { "Content-Type": "application/json" },
|
|
48
56
|
});
|
|
49
57
|
if (!res.data.success) {
|
|
50
58
|
throw new Error(`Failed to create project: ${JSON.stringify(res.data)}`);
|
|
@@ -53,7 +61,7 @@ export async function createProjectOrFolder(args) {
|
|
|
53
61
|
projId = res.data.project.identifier;
|
|
54
62
|
}
|
|
55
63
|
catch (err) {
|
|
56
|
-
return formatAxiosError(err, "Failed to create project
|
|
64
|
+
return formatAxiosError(err, "Failed to create project.");
|
|
57
65
|
}
|
|
58
66
|
}
|
|
59
67
|
// Step 2: Create folder if folder_name provided
|
|
@@ -61,25 +69,27 @@ export async function createProjectOrFolder(args) {
|
|
|
61
69
|
if (!projId)
|
|
62
70
|
throw new Error("Cannot create folder without project_identifier.");
|
|
63
71
|
try {
|
|
64
|
-
const res = await
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
72
|
+
const res = await apiClient.post({
|
|
73
|
+
url: `https://test-management.browserstack.com/api/v2/projects/${encodeURIComponent(projId)}/folders`,
|
|
74
|
+
headers: {
|
|
75
|
+
"Content-Type": "application/json",
|
|
76
|
+
Authorization: "Basic " +
|
|
77
|
+
Buffer.from(`${username}:${password}`).toString("base64"),
|
|
69
78
|
},
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
79
|
+
body: {
|
|
80
|
+
folder: {
|
|
81
|
+
name: folder_name,
|
|
82
|
+
description: folder_description,
|
|
83
|
+
parent_id,
|
|
84
|
+
},
|
|
74
85
|
},
|
|
75
|
-
headers: { "Content-Type": "application/json" },
|
|
76
86
|
});
|
|
77
87
|
if (!res.data.success) {
|
|
78
88
|
throw new Error(`Failed to create folder: ${JSON.stringify(res.data)}`);
|
|
79
89
|
}
|
|
80
90
|
// Folder created successfully
|
|
81
91
|
const folder = res.data.folder;
|
|
82
|
-
const projectId = await projectIdentifierToId(projId);
|
|
92
|
+
const projectId = await projectIdentifierToId(projId, config);
|
|
83
93
|
return {
|
|
84
94
|
content: [
|
|
85
95
|
{
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
import { BrowserStackConfig } from "../../lib/types.js";
|
|
4
|
+
interface TestCaseStep {
|
|
5
|
+
step: string;
|
|
6
|
+
result: string;
|
|
7
|
+
}
|
|
8
|
+
interface IssueTracker {
|
|
9
|
+
name: string;
|
|
10
|
+
host: string;
|
|
11
|
+
}
|
|
12
|
+
export interface TestCaseCreateRequest {
|
|
13
|
+
project_identifier: string;
|
|
14
|
+
folder_id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
owner?: string;
|
|
18
|
+
preconditions?: string;
|
|
19
|
+
test_case_steps: TestCaseStep[];
|
|
20
|
+
issues?: string[];
|
|
21
|
+
issue_tracker?: IssueTracker;
|
|
22
|
+
tags?: string[];
|
|
23
|
+
custom_fields?: Record<string, string>;
|
|
24
|
+
}
|
|
25
|
+
export interface TestCaseResponse {
|
|
26
|
+
data: {
|
|
27
|
+
success: boolean;
|
|
28
|
+
test_case: {
|
|
29
|
+
case_type: string;
|
|
30
|
+
priority: string;
|
|
31
|
+
status: string;
|
|
32
|
+
folder_id: number;
|
|
33
|
+
issues: Array<{
|
|
34
|
+
jira_id: string;
|
|
35
|
+
issue_type: string;
|
|
36
|
+
}>;
|
|
37
|
+
tags: string[];
|
|
38
|
+
template: string;
|
|
39
|
+
description: string;
|
|
40
|
+
preconditions: string;
|
|
41
|
+
title: string;
|
|
42
|
+
identifier: string;
|
|
43
|
+
automation_status: string;
|
|
44
|
+
owner: string;
|
|
45
|
+
steps: TestCaseStep[];
|
|
46
|
+
custom_fields: Array<{
|
|
47
|
+
name: string;
|
|
48
|
+
value: string;
|
|
49
|
+
}>;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export declare const CreateTestCaseSchema: z.ZodObject<{
|
|
54
|
+
project_identifier: z.ZodString;
|
|
55
|
+
folder_id: z.ZodString;
|
|
56
|
+
name: z.ZodString;
|
|
57
|
+
description: z.ZodOptional<z.ZodString>;
|
|
58
|
+
owner: z.ZodOptional<z.ZodString>;
|
|
59
|
+
preconditions: z.ZodOptional<z.ZodString>;
|
|
60
|
+
test_case_steps: z.ZodArray<z.ZodObject<{
|
|
61
|
+
step: z.ZodString;
|
|
62
|
+
result: z.ZodString;
|
|
63
|
+
}, "strip", z.ZodTypeAny, {
|
|
64
|
+
step: string;
|
|
65
|
+
result: string;
|
|
66
|
+
}, {
|
|
67
|
+
step: string;
|
|
68
|
+
result: string;
|
|
69
|
+
}>, "many">;
|
|
70
|
+
issues: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
71
|
+
issue_tracker: z.ZodOptional<z.ZodObject<{
|
|
72
|
+
name: z.ZodString;
|
|
73
|
+
host: z.ZodString;
|
|
74
|
+
}, "strip", z.ZodTypeAny, {
|
|
75
|
+
name: string;
|
|
76
|
+
host: string;
|
|
77
|
+
}, {
|
|
78
|
+
name: string;
|
|
79
|
+
host: string;
|
|
80
|
+
}>>;
|
|
81
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
82
|
+
custom_fields: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
83
|
+
}, "strip", z.ZodTypeAny, {
|
|
84
|
+
name: string;
|
|
85
|
+
test_case_steps: {
|
|
86
|
+
step: string;
|
|
87
|
+
result: string;
|
|
88
|
+
}[];
|
|
89
|
+
project_identifier: string;
|
|
90
|
+
folder_id: string;
|
|
91
|
+
issues?: string[] | undefined;
|
|
92
|
+
description?: string | undefined;
|
|
93
|
+
tags?: string[] | undefined;
|
|
94
|
+
custom_fields?: Record<string, string> | undefined;
|
|
95
|
+
preconditions?: string | undefined;
|
|
96
|
+
owner?: string | undefined;
|
|
97
|
+
issue_tracker?: {
|
|
98
|
+
name: string;
|
|
99
|
+
host: string;
|
|
100
|
+
} | undefined;
|
|
101
|
+
}, {
|
|
102
|
+
name: string;
|
|
103
|
+
test_case_steps: {
|
|
104
|
+
step: string;
|
|
105
|
+
result: string;
|
|
106
|
+
}[];
|
|
107
|
+
project_identifier: string;
|
|
108
|
+
folder_id: string;
|
|
109
|
+
issues?: string[] | undefined;
|
|
110
|
+
description?: string | undefined;
|
|
111
|
+
tags?: string[] | undefined;
|
|
112
|
+
custom_fields?: Record<string, string> | undefined;
|
|
113
|
+
preconditions?: string | undefined;
|
|
114
|
+
owner?: string | undefined;
|
|
115
|
+
issue_tracker?: {
|
|
116
|
+
name: string;
|
|
117
|
+
host: string;
|
|
118
|
+
} | undefined;
|
|
119
|
+
}>;
|
|
120
|
+
export declare function sanitizeArgs(args: any): any;
|
|
121
|
+
export declare function createTestCase(params: TestCaseCreateRequest, config: BrowserStackConfig): Promise<CallToolResult>;
|
|
122
|
+
export {};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import config from "../../config.js";
|
|
1
|
+
import { apiClient } from "../../lib/apiClient.js";
|
|
3
2
|
import { z } from "zod";
|
|
4
|
-
import { formatAxiosError } from "../../lib/error.js";
|
|
3
|
+
import { formatAxiosError } from "../../lib/error.js";
|
|
5
4
|
import { projectIdentifierToId } from "./TCG-utils/api.js";
|
|
6
5
|
export const CreateTestCaseSchema = z.object({
|
|
7
6
|
project_identifier: z
|
|
@@ -67,15 +66,19 @@ export function sanitizeArgs(args) {
|
|
|
67
66
|
}
|
|
68
67
|
return cleaned;
|
|
69
68
|
}
|
|
70
|
-
|
|
69
|
+
import { getBrowserStackAuth } from "../../lib/get-auth.js";
|
|
70
|
+
export async function createTestCase(params, config) {
|
|
71
71
|
const body = { test_case: params };
|
|
72
|
+
const authString = getBrowserStackAuth(config);
|
|
73
|
+
const [username, password] = authString.split(":");
|
|
72
74
|
try {
|
|
73
|
-
const response = await
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
const response = await apiClient.post({
|
|
76
|
+
url: `https://test-management.browserstack.com/api/v2/projects/${encodeURIComponent(params.project_identifier)}/folders/${encodeURIComponent(params.folder_id)}/test-cases`,
|
|
77
|
+
headers: {
|
|
78
|
+
"Content-Type": "application/json",
|
|
79
|
+
Authorization: "Basic " + Buffer.from(`${username}:${password}`).toString("base64"),
|
|
77
80
|
},
|
|
78
|
-
|
|
81
|
+
body,
|
|
79
82
|
});
|
|
80
83
|
const { data } = response.data;
|
|
81
84
|
if (!data.success) {
|
|
@@ -91,7 +94,7 @@ export async function createTestCase(params) {
|
|
|
91
94
|
};
|
|
92
95
|
}
|
|
93
96
|
const tc = data.test_case;
|
|
94
|
-
const projectId = await projectIdentifierToId(params.project_identifier);
|
|
97
|
+
const projectId = await projectIdentifierToId(params.project_identifier, config);
|
|
95
98
|
return {
|
|
96
99
|
content: [
|
|
97
100
|
{
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
import { BrowserStackConfig } from "../../lib/types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Schema for creating a test run.
|
|
6
|
+
*/
|
|
7
|
+
export declare const CreateTestRunSchema: z.ZodObject<{
|
|
8
|
+
project_identifier: z.ZodString;
|
|
9
|
+
test_run: z.ZodObject<{
|
|
10
|
+
name: z.ZodString;
|
|
11
|
+
description: z.ZodOptional<z.ZodString>;
|
|
12
|
+
run_state: z.ZodOptional<z.ZodEnum<["new_run", "in_progress", "under_review", "rejected", "done", "closed"]>>;
|
|
13
|
+
issues: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
14
|
+
issue_tracker: z.ZodOptional<z.ZodObject<{
|
|
15
|
+
name: z.ZodString;
|
|
16
|
+
host: z.ZodString;
|
|
17
|
+
}, "strip", z.ZodTypeAny, {
|
|
18
|
+
name: string;
|
|
19
|
+
host: string;
|
|
20
|
+
}, {
|
|
21
|
+
name: string;
|
|
22
|
+
host: string;
|
|
23
|
+
}>>;
|
|
24
|
+
test_cases: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
25
|
+
folder_ids: z.ZodOptional<z.ZodArray<z.ZodNumber, "many">>;
|
|
26
|
+
}, "strip", z.ZodTypeAny, {
|
|
27
|
+
name: string;
|
|
28
|
+
issues?: string[] | undefined;
|
|
29
|
+
description?: string | undefined;
|
|
30
|
+
issue_tracker?: {
|
|
31
|
+
name: string;
|
|
32
|
+
host: string;
|
|
33
|
+
} | undefined;
|
|
34
|
+
test_cases?: string[] | undefined;
|
|
35
|
+
run_state?: "new_run" | "in_progress" | "under_review" | "rejected" | "done" | "closed" | undefined;
|
|
36
|
+
folder_ids?: number[] | undefined;
|
|
37
|
+
}, {
|
|
38
|
+
name: string;
|
|
39
|
+
issues?: string[] | undefined;
|
|
40
|
+
description?: string | undefined;
|
|
41
|
+
issue_tracker?: {
|
|
42
|
+
name: string;
|
|
43
|
+
host: string;
|
|
44
|
+
} | undefined;
|
|
45
|
+
test_cases?: string[] | undefined;
|
|
46
|
+
run_state?: "new_run" | "in_progress" | "under_review" | "rejected" | "done" | "closed" | undefined;
|
|
47
|
+
folder_ids?: number[] | undefined;
|
|
48
|
+
}>;
|
|
49
|
+
}, "strip", z.ZodTypeAny, {
|
|
50
|
+
project_identifier: string;
|
|
51
|
+
test_run: {
|
|
52
|
+
name: string;
|
|
53
|
+
issues?: string[] | undefined;
|
|
54
|
+
description?: string | undefined;
|
|
55
|
+
issue_tracker?: {
|
|
56
|
+
name: string;
|
|
57
|
+
host: string;
|
|
58
|
+
} | undefined;
|
|
59
|
+
test_cases?: string[] | undefined;
|
|
60
|
+
run_state?: "new_run" | "in_progress" | "under_review" | "rejected" | "done" | "closed" | undefined;
|
|
61
|
+
folder_ids?: number[] | undefined;
|
|
62
|
+
};
|
|
63
|
+
}, {
|
|
64
|
+
project_identifier: string;
|
|
65
|
+
test_run: {
|
|
66
|
+
name: string;
|
|
67
|
+
issues?: string[] | undefined;
|
|
68
|
+
description?: string | undefined;
|
|
69
|
+
issue_tracker?: {
|
|
70
|
+
name: string;
|
|
71
|
+
host: string;
|
|
72
|
+
} | undefined;
|
|
73
|
+
test_cases?: string[] | undefined;
|
|
74
|
+
run_state?: "new_run" | "in_progress" | "under_review" | "rejected" | "done" | "closed" | undefined;
|
|
75
|
+
folder_ids?: number[] | undefined;
|
|
76
|
+
};
|
|
77
|
+
}>;
|
|
78
|
+
export type CreateTestRunArgs = z.infer<typeof CreateTestRunSchema>;
|
|
79
|
+
/**
|
|
80
|
+
* Creates a test run via BrowserStack Test Management API.
|
|
81
|
+
*/
|
|
82
|
+
export declare function createTestRun(rawArgs: CreateTestRunArgs, config: BrowserStackConfig): Promise<CallToolResult>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import config from "../../config.js";
|
|
1
|
+
import { apiClient } from "../../lib/apiClient.js";
|
|
3
2
|
import { z } from "zod";
|
|
4
3
|
import { formatAxiosError } from "../../lib/error.js";
|
|
4
|
+
import { getBrowserStackAuth } from "../../lib/get-auth.js";
|
|
5
5
|
/**
|
|
6
6
|
* Schema for creating a test run.
|
|
7
7
|
*/
|
|
@@ -44,7 +44,7 @@ export const CreateTestRunSchema = z.object({
|
|
|
44
44
|
/**
|
|
45
45
|
* Creates a test run via BrowserStack Test Management API.
|
|
46
46
|
*/
|
|
47
|
-
export async function createTestRun(rawArgs) {
|
|
47
|
+
export async function createTestRun(rawArgs, config) {
|
|
48
48
|
try {
|
|
49
49
|
const inputArgs = {
|
|
50
50
|
...rawArgs,
|
|
@@ -55,12 +55,15 @@ export async function createTestRun(rawArgs) {
|
|
|
55
55
|
};
|
|
56
56
|
const args = CreateTestRunSchema.parse(inputArgs);
|
|
57
57
|
const url = `https://test-management.browserstack.com/api/v2/projects/${encodeURIComponent(args.project_identifier)}/test-runs`;
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
const authString = getBrowserStackAuth(config);
|
|
59
|
+
const [username, password] = authString.split(":");
|
|
60
|
+
const response = await apiClient.post({
|
|
61
|
+
url,
|
|
62
|
+
headers: {
|
|
63
|
+
"Content-Type": "application/json",
|
|
64
|
+
Authorization: "Basic " + Buffer.from(`${username}:${password}`).toString("base64"),
|
|
62
65
|
},
|
|
63
|
-
|
|
66
|
+
body: { test_run: args.test_run },
|
|
64
67
|
});
|
|
65
68
|
const data = response.data;
|
|
66
69
|
if (!data.success) {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
import { BrowserStackConfig } from "../../lib/types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Schema for listing test cases with optional filters.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ListTestCasesSchema: z.ZodObject<{
|
|
8
|
+
project_identifier: z.ZodString;
|
|
9
|
+
folder_id: z.ZodOptional<z.ZodString>;
|
|
10
|
+
case_type: z.ZodOptional<z.ZodString>;
|
|
11
|
+
priority: z.ZodOptional<z.ZodString>;
|
|
12
|
+
p: z.ZodOptional<z.ZodNumber>;
|
|
13
|
+
}, "strip", z.ZodTypeAny, {
|
|
14
|
+
project_identifier: string;
|
|
15
|
+
priority?: string | undefined;
|
|
16
|
+
case_type?: string | undefined;
|
|
17
|
+
folder_id?: string | undefined;
|
|
18
|
+
p?: number | undefined;
|
|
19
|
+
}, {
|
|
20
|
+
project_identifier: string;
|
|
21
|
+
priority?: string | undefined;
|
|
22
|
+
case_type?: string | undefined;
|
|
23
|
+
folder_id?: string | undefined;
|
|
24
|
+
p?: number | undefined;
|
|
25
|
+
}>;
|
|
26
|
+
export type ListTestCasesArgs = z.infer<typeof ListTestCasesSchema>;
|
|
27
|
+
/**
|
|
28
|
+
* Calls BrowserStack Test Management to list test cases with filters.
|
|
29
|
+
*/
|
|
30
|
+
export declare function listTestCases(args: ListTestCasesArgs, config: BrowserStackConfig): Promise<CallToolResult>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import config from "../../config.js";
|
|
1
|
+
import { apiClient } from "../../lib/apiClient.js";
|
|
3
2
|
import { z } from "zod";
|
|
4
3
|
import { formatAxiosError } from "../../lib/error.js";
|
|
4
|
+
import { getBrowserStackAuth } from "../../lib/get-auth.js";
|
|
5
5
|
/**
|
|
6
6
|
* Schema for listing test cases with optional filters.
|
|
7
7
|
*/
|
|
@@ -26,7 +26,7 @@ export const ListTestCasesSchema = z.object({
|
|
|
26
26
|
/**
|
|
27
27
|
* Calls BrowserStack Test Management to list test cases with filters.
|
|
28
28
|
*/
|
|
29
|
-
export async function listTestCases(args) {
|
|
29
|
+
export async function listTestCases(args, config) {
|
|
30
30
|
try {
|
|
31
31
|
// Build query string
|
|
32
32
|
const params = new URLSearchParams();
|
|
@@ -39,10 +39,12 @@ export async function listTestCases(args) {
|
|
|
39
39
|
if (args.p !== undefined)
|
|
40
40
|
params.append("p", args.p.toString());
|
|
41
41
|
const url = `https://test-management.browserstack.com/api/v2/projects/${encodeURIComponent(args.project_identifier)}/test-cases?${params.toString()}`;
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
const authString = getBrowserStackAuth(config);
|
|
43
|
+
const [username, password] = authString.split(":");
|
|
44
|
+
const resp = await apiClient.get({
|
|
45
|
+
url,
|
|
46
|
+
headers: {
|
|
47
|
+
Authorization: "Basic " + Buffer.from(`${username}:${password}`).toString("base64"),
|
|
46
48
|
},
|
|
47
49
|
});
|
|
48
50
|
const resp_data = resp.data;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
import { BrowserStackConfig } from "../../lib/types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Schema for listing test runs with optional filters.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ListTestRunsSchema: z.ZodObject<{
|
|
8
|
+
project_identifier: z.ZodString;
|
|
9
|
+
run_state: z.ZodOptional<z.ZodString>;
|
|
10
|
+
}, "strip", z.ZodTypeAny, {
|
|
11
|
+
project_identifier: string;
|
|
12
|
+
run_state?: string | undefined;
|
|
13
|
+
}, {
|
|
14
|
+
project_identifier: string;
|
|
15
|
+
run_state?: string | undefined;
|
|
16
|
+
}>;
|
|
17
|
+
type ListTestRunsArgs = z.infer<typeof ListTestRunsSchema>;
|
|
18
|
+
/**
|
|
19
|
+
* Fetches and formats the list of test runs for a project.
|
|
20
|
+
*/
|
|
21
|
+
export declare function listTestRuns(args: ListTestRunsArgs, config: BrowserStackConfig): Promise<CallToolResult>;
|
|
22
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import config from "../../config.js";
|
|
1
|
+
import { apiClient } from "../../lib/apiClient.js";
|
|
3
2
|
import { z } from "zod";
|
|
4
3
|
import { formatAxiosError } from "../../lib/error.js";
|
|
4
|
+
import { getBrowserStackAuth } from "../../lib/get-auth.js";
|
|
5
5
|
/**
|
|
6
6
|
* Schema for listing test runs with optional filters.
|
|
7
7
|
*/
|
|
@@ -17,17 +17,19 @@ export const ListTestRunsSchema = z.object({
|
|
|
17
17
|
/**
|
|
18
18
|
* Fetches and formats the list of test runs for a project.
|
|
19
19
|
*/
|
|
20
|
-
export async function listTestRuns(args) {
|
|
20
|
+
export async function listTestRuns(args, config) {
|
|
21
21
|
try {
|
|
22
22
|
const params = new URLSearchParams();
|
|
23
23
|
if (args.run_state) {
|
|
24
24
|
params.set("run_state", args.run_state);
|
|
25
25
|
}
|
|
26
26
|
const url = `https://test-management.browserstack.com/api/v2/projects/${encodeURIComponent(args.project_identifier)}/test-runs?` + params.toString();
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
const authString = getBrowserStackAuth(config);
|
|
28
|
+
const [username, password] = authString.split(":");
|
|
29
|
+
const resp = await apiClient.get({
|
|
30
|
+
url,
|
|
31
|
+
headers: {
|
|
32
|
+
Authorization: "Basic " + Buffer.from(`${username}:${password}`).toString("base64"),
|
|
31
33
|
},
|
|
32
34
|
});
|
|
33
35
|
const data = resp.data;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BrowserStackConfig } from "../../lib/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Poll test case details to check LCA build status
|
|
4
|
+
*/
|
|
5
|
+
export declare function pollLCAStatus(projectId: string, folderId: string, testCaseId: string, context: any, maxWaitTimeMs: number | undefined, // 10 minutes default
|
|
6
|
+
initialWaitMs: number | undefined, // 2 minutes initial wait
|
|
7
|
+
pollIntervalMs: number | undefined, // 10 seconds interval
|
|
8
|
+
config: BrowserStackConfig): Promise<{
|
|
9
|
+
resource_path: string;
|
|
10
|
+
status: string;
|
|
11
|
+
} | null>;
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { apiClient } from "../../lib/apiClient.js";
|
|
2
|
+
import { getBrowserStackAuth } from "../../lib/get-auth.js";
|
|
3
3
|
/**
|
|
4
4
|
* Poll test case details to check LCA build status
|
|
5
5
|
*/
|
|
6
6
|
export async function pollLCAStatus(projectId, folderId, testCaseId, context, maxWaitTimeMs = 10 * 60 * 1000, // 10 minutes default
|
|
7
7
|
initialWaitMs = 2 * 60 * 1000, // 2 minutes initial wait
|
|
8
|
-
pollIntervalMs = 10 * 1000
|
|
8
|
+
pollIntervalMs = 10 * 1000, // 10 seconds interval
|
|
9
|
+
config) {
|
|
9
10
|
const url = `https://test-management.browserstack.com/api/v1/projects/${projectId}/folder/${folderId}/test-cases/${testCaseId}`;
|
|
10
11
|
const startTime = Date.now();
|
|
11
12
|
// Send initial notification that polling is starting
|
|
@@ -49,17 +50,20 @@ pollIntervalMs = 10 * 1000) {
|
|
|
49
50
|
// Set up polling interval
|
|
50
51
|
const intervalId = setInterval(async () => {
|
|
51
52
|
try {
|
|
52
|
-
const
|
|
53
|
+
const authString = getBrowserStackAuth(config);
|
|
54
|
+
const response = await apiClient.get({
|
|
55
|
+
url,
|
|
53
56
|
headers: {
|
|
54
|
-
"API-TOKEN":
|
|
57
|
+
"API-TOKEN": authString,
|
|
55
58
|
accept: "application/json, text/plain, */*",
|
|
56
59
|
},
|
|
57
60
|
});
|
|
58
|
-
|
|
59
|
-
|
|
61
|
+
const responseData = response.data;
|
|
62
|
+
if (responseData.data.success && responseData.data.test_case) {
|
|
63
|
+
const testCase = responseData.data.test_case;
|
|
60
64
|
// Check lcnc_build_map in both possible locations
|
|
61
65
|
const lcncBuildMap = testCase.lcnc_build_map ||
|
|
62
|
-
|
|
66
|
+
responseData.data.metadata?.lcnc_build_map;
|
|
63
67
|
if (lcncBuildMap) {
|
|
64
68
|
if (lcncBuildMap.status === "done") {
|
|
65
69
|
// Clean up timers
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { CreateTestCasesFromFileArgs } from "./TCG-utils/types.js";
|
|
2
|
+
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
import { BrowserStackConfig } from "../../lib/types.js";
|
|
4
|
+
export declare function createTestCasesFromFile(args: CreateTestCasesFromFileArgs, context: any, config: BrowserStackConfig): Promise<CallToolResult>;
|
|
@@ -3,12 +3,12 @@ import { buildDefaultFieldMaps, findBooleanFieldId, } from "./TCG-utils/helpers.
|
|
|
3
3
|
import { signedUrlMap } from "../../lib/inmemory-store.js";
|
|
4
4
|
import logger from "../../logger.js";
|
|
5
5
|
import { projectIdentifierToId } from "./TCG-utils/api.js";
|
|
6
|
-
export async function createTestCasesFromFile(args, context) {
|
|
6
|
+
export async function createTestCasesFromFile(args, context, config) {
|
|
7
7
|
logger.info(`createTestCasesFromFile called with projectId: ${args.projectReferenceId}, folderId: ${args.folderId}`);
|
|
8
8
|
if (args.projectReferenceId.startsWith("PR-")) {
|
|
9
|
-
args.projectReferenceId = await projectIdentifierToId(args.projectReferenceId);
|
|
9
|
+
args.projectReferenceId = await projectIdentifierToId(args.projectReferenceId, config);
|
|
10
10
|
}
|
|
11
|
-
const { default_fields, custom_fields } = await fetchFormFields(args.projectReferenceId);
|
|
11
|
+
const { default_fields, custom_fields } = await fetchFormFields(args.projectReferenceId, config);
|
|
12
12
|
const fieldMaps = buildDefaultFieldMaps(default_fields);
|
|
13
13
|
const booleanFieldId = findBooleanFieldId(custom_fields);
|
|
14
14
|
const documentObj = signedUrlMap.get(args.documentId);
|
|
@@ -27,9 +27,9 @@ export async function createTestCasesFromFile(args, context) {
|
|
|
27
27
|
const documentId = documentObj.fileId;
|
|
28
28
|
const document = documentObj.downloadUrl;
|
|
29
29
|
const source = "jira-on-prem";
|
|
30
|
-
const traceId = await triggerTestCaseGeneration(document, documentId, args.folderId, args.projectReferenceId, source);
|
|
31
|
-
const scenariosMap = await pollScenariosTestDetails(args, traceId, context, documentId, source);
|
|
32
|
-
const resultString = await bulkCreateTestCases(scenariosMap, args.projectReferenceId, args.folderId, fieldMaps, booleanFieldId, traceId, context, documentId);
|
|
30
|
+
const traceId = await triggerTestCaseGeneration(document, documentId, args.folderId, args.projectReferenceId, source, config);
|
|
31
|
+
const scenariosMap = await pollScenariosTestDetails(args, traceId, context, documentId, source, config);
|
|
32
|
+
const resultString = await bulkCreateTestCases(scenariosMap, args.projectReferenceId, args.folderId, fieldMaps, booleanFieldId, traceId, context, documentId, config);
|
|
33
33
|
signedUrlMap.delete(args.documentId);
|
|
34
34
|
const dashboardURL = `https://test-management.browserstack.com/projects/${args.projectReferenceId}/folder/${args.folderId}/test-cases`;
|
|
35
35
|
return {
|