@browserstack/mcp-server 1.0.14 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.js +6 -2
- package/dist/index.js +34 -31
- package/dist/lib/api.js +9 -3
- package/dist/lib/constants.js +6 -3
- package/dist/lib/device-cache.js +21 -14
- package/dist/lib/error.js +6 -3
- package/dist/lib/fuzzy.js +4 -1
- package/dist/lib/inmemory-store.js +4 -1
- package/dist/lib/instrumentation.js +18 -12
- package/dist/lib/local.js +35 -27
- package/dist/lib/utils.js +15 -6
- package/dist/logger.js +6 -4
- package/dist/tools/accessibility.js +54 -18
- package/dist/tools/accessiblity-utils/report-fetcher.js +35 -0
- package/dist/tools/accessiblity-utils/report-parser.js +57 -0
- package/dist/tools/accessiblity-utils/scanner.js +87 -0
- package/dist/tools/appautomate-utils/appautomate.js +27 -17
- package/dist/tools/appautomate.js +35 -29
- package/dist/tools/applive-utils/fuzzy-search.js +6 -3
- package/dist/tools/applive-utils/start-session.js +20 -14
- package/dist/tools/applive-utils/upload-app.js +51 -12
- package/dist/tools/applive.js +25 -18
- package/dist/tools/automate-utils/fetch-screenshots.js +14 -8
- package/dist/tools/automate.js +21 -14
- package/dist/tools/bstack-sdk.js +18 -14
- package/dist/tools/failurelogs-utils/app-automate.js +26 -15
- package/dist/tools/failurelogs-utils/automate.js +23 -13
- package/dist/tools/getFailureLogs.js +49 -42
- package/dist/tools/live-utils/desktop-filter.js +11 -8
- package/dist/tools/live-utils/mobile-filter.js +10 -7
- package/dist/tools/live-utils/start-session.js +23 -17
- package/dist/tools/live-utils/types.js +5 -2
- package/dist/tools/live-utils/version-resolver.js +4 -1
- package/dist/tools/live.js +29 -23
- package/dist/tools/observability.js +19 -12
- package/dist/tools/sdk-utils/constants.js +9 -3
- package/dist/tools/sdk-utils/instructions.js +9 -4
- package/dist/tools/sdk-utils/types.js +2 -1
- package/dist/tools/testmanagement-utils/TCG-utils/api.js +38 -26
- package/dist/tools/testmanagement-utils/TCG-utils/config.js +10 -5
- package/dist/tools/testmanagement-utils/TCG-utils/helpers.js +8 -3
- package/dist/tools/testmanagement-utils/TCG-utils/types.js +8 -5
- package/dist/tools/testmanagement-utils/add-test-result.js +24 -17
- package/dist/tools/testmanagement-utils/create-project-folder.js +28 -21
- package/dist/tools/testmanagement-utils/create-testcase.js +38 -30
- package/dist/tools/testmanagement-utils/create-testrun.js +30 -23
- package/dist/tools/testmanagement-utils/list-testcases.js +22 -15
- package/dist/tools/testmanagement-utils/list-testruns.js +19 -12
- package/dist/tools/testmanagement-utils/testcase-from-file.js +22 -16
- package/dist/tools/testmanagement-utils/update-testrun.js +22 -15
- package/dist/tools/testmanagement-utils/upload-file.js +29 -22
- package/dist/tools/testmanagement.js +76 -61
- package/package.json +4 -2
- package/dist/tools/accessiblity-utils/accessibility.js +0 -74
|
@@ -1,31 +1,38 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.UploadFileSchema = void 0;
|
|
7
|
+
exports.uploadFile = uploadFile;
|
|
8
|
+
const zod_1 = require("zod");
|
|
9
|
+
const axios_1 = __importDefault(require("axios"));
|
|
10
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const path_1 = __importDefault(require("path"));
|
|
13
|
+
const uuid_1 = require("uuid");
|
|
14
|
+
const config_js_1 = __importDefault(require("../../config.js"));
|
|
15
|
+
const inmemory_store_js_1 = require("../../lib/inmemory-store.js");
|
|
16
|
+
const api_js_1 = require("./TCG-utils/api.js");
|
|
10
17
|
/**
|
|
11
18
|
* Schema for the upload file tool
|
|
12
19
|
*/
|
|
13
|
-
|
|
14
|
-
project_identifier: z
|
|
20
|
+
exports.UploadFileSchema = zod_1.z.object({
|
|
21
|
+
project_identifier: zod_1.z
|
|
15
22
|
.string()
|
|
16
23
|
.describe("ID of the project where the file should be uploaded. Do not assume it, always ask user for it."),
|
|
17
|
-
file_path: z
|
|
24
|
+
file_path: zod_1.z
|
|
18
25
|
.string()
|
|
19
26
|
.describe("Full path to the file that should be uploaded"),
|
|
20
27
|
});
|
|
21
28
|
/**
|
|
22
29
|
* Uploads a file to BrowserStack Test Management and returns the signed URL.
|
|
23
30
|
*/
|
|
24
|
-
|
|
31
|
+
async function uploadFile(args) {
|
|
25
32
|
const { project_identifier, file_path } = args;
|
|
26
33
|
try {
|
|
27
34
|
// Validate file exists
|
|
28
|
-
if (!
|
|
35
|
+
if (!fs_1.default.existsSync(file_path)) {
|
|
29
36
|
return {
|
|
30
37
|
content: [
|
|
31
38
|
{
|
|
@@ -38,14 +45,14 @@ export async function uploadFile(args) {
|
|
|
38
45
|
};
|
|
39
46
|
}
|
|
40
47
|
// Get the project ID
|
|
41
|
-
const projectIdResponse = await projectIdentifierToId(project_identifier);
|
|
42
|
-
const formData = new
|
|
43
|
-
formData.append("attachments[]",
|
|
48
|
+
const projectIdResponse = await (0, api_js_1.projectIdentifierToId)(project_identifier);
|
|
49
|
+
const formData = new form_data_1.default();
|
|
50
|
+
formData.append("attachments[]", fs_1.default.createReadStream(file_path));
|
|
44
51
|
const uploadUrl = `https://test-management.browserstack.com/api/v1/projects/${projectIdResponse}/generic/attachments/ai_uploads`;
|
|
45
|
-
const response = await
|
|
52
|
+
const response = await axios_1.default.post(uploadUrl, formData, {
|
|
46
53
|
headers: {
|
|
47
54
|
...formData.getHeaders(),
|
|
48
|
-
"API-TOKEN": `${
|
|
55
|
+
"API-TOKEN": `${config_js_1.default.browserstackUsername}:${config_js_1.default.browserstackAccessKey}`,
|
|
49
56
|
accept: "application/json, text/plain, */*",
|
|
50
57
|
},
|
|
51
58
|
});
|
|
@@ -54,13 +61,13 @@ export async function uploadFile(args) {
|
|
|
54
61
|
response.data.generic_attachment) {
|
|
55
62
|
const attachments = response.data.generic_attachment.map((attachment) => {
|
|
56
63
|
// Generate a unique ID for each attachment
|
|
57
|
-
const fileId =
|
|
64
|
+
const fileId = (0, uuid_1.v4)();
|
|
58
65
|
// Store the download URL in the signedUrlMap
|
|
59
66
|
const data = {
|
|
60
67
|
fileId: attachment.id,
|
|
61
68
|
downloadUrl: attachment.download_url,
|
|
62
69
|
};
|
|
63
|
-
signedUrlMap.set(fileId, data);
|
|
70
|
+
inmemory_store_js_1.signedUrlMap.set(fileId, data);
|
|
64
71
|
return {
|
|
65
72
|
name: attachment.name,
|
|
66
73
|
documentID: fileId,
|
|
@@ -73,7 +80,7 @@ export async function uploadFile(args) {
|
|
|
73
80
|
content: [
|
|
74
81
|
{
|
|
75
82
|
type: "text",
|
|
76
|
-
text: `Successfully uploaded ${
|
|
83
|
+
text: `Successfully uploaded ${path_1.default.basename(file_path)} to BrowserStack Test Management.`,
|
|
77
84
|
},
|
|
78
85
|
{
|
|
79
86
|
type: "text",
|
|
@@ -1,28 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createProjectOrFolderTool = createProjectOrFolderTool;
|
|
7
|
+
exports.createTestCaseTool = createTestCaseTool;
|
|
8
|
+
exports.listTestCasesTool = listTestCasesTool;
|
|
9
|
+
exports.createTestRunTool = createTestRunTool;
|
|
10
|
+
exports.listTestRunsTool = listTestRunsTool;
|
|
11
|
+
exports.updateTestRunTool = updateTestRunTool;
|
|
12
|
+
exports.addTestResultTool = addTestResultTool;
|
|
13
|
+
exports.uploadProductRequirementFileTool = uploadProductRequirementFileTool;
|
|
14
|
+
exports.createTestCasesFromFileTool = createTestCasesFromFileTool;
|
|
15
|
+
exports.default = addTestManagementTools;
|
|
16
|
+
const instrumentation_js_1 = require("../lib/instrumentation.js");
|
|
17
|
+
const logger_js_1 = __importDefault(require("../logger.js"));
|
|
18
|
+
const create_project_folder_js_1 = require("./testmanagement-utils/create-project-folder.js");
|
|
19
|
+
const create_testcase_js_1 = require("./testmanagement-utils/create-testcase.js");
|
|
5
20
|
let serverInstance;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
21
|
+
const list_testcases_js_1 = require("./testmanagement-utils/list-testcases.js");
|
|
22
|
+
const create_testrun_js_1 = require("./testmanagement-utils/create-testrun.js");
|
|
23
|
+
const list_testruns_js_1 = require("./testmanagement-utils/list-testruns.js");
|
|
24
|
+
const update_testrun_js_1 = require("./testmanagement-utils/update-testrun.js");
|
|
25
|
+
const add_test_result_js_1 = require("./testmanagement-utils/add-test-result.js");
|
|
26
|
+
const upload_file_js_1 = require("./testmanagement-utils/upload-file.js");
|
|
27
|
+
const testcase_from_file_js_1 = require("./testmanagement-utils/testcase-from-file.js");
|
|
28
|
+
const types_js_1 = require("./testmanagement-utils/TCG-utils/types.js");
|
|
14
29
|
//TODO: Moving the traceMCP and catch block to the parent(server) function
|
|
15
30
|
/**
|
|
16
31
|
* Wrapper to call createProjectOrFolder util.
|
|
17
32
|
*/
|
|
18
|
-
|
|
33
|
+
async function createProjectOrFolderTool(args) {
|
|
19
34
|
try {
|
|
20
|
-
trackMCP("createProjectOrFolder", serverInstance.server.getClientVersion());
|
|
21
|
-
return await createProjectOrFolder(args);
|
|
35
|
+
(0, instrumentation_js_1.trackMCP)("createProjectOrFolder", serverInstance.server.getClientVersion());
|
|
36
|
+
return await (0, create_project_folder_js_1.createProjectOrFolder)(args);
|
|
22
37
|
}
|
|
23
38
|
catch (err) {
|
|
24
|
-
|
|
25
|
-
trackMCP("createProjectOrFolder", serverInstance.server.getClientVersion(), err);
|
|
39
|
+
logger_js_1.default.error("Failed to create project/folder: %s", err);
|
|
40
|
+
(0, instrumentation_js_1.trackMCP)("createProjectOrFolder", serverInstance.server.getClientVersion(), err);
|
|
26
41
|
return {
|
|
27
42
|
content: [
|
|
28
43
|
{
|
|
@@ -38,16 +53,16 @@ export async function createProjectOrFolderTool(args) {
|
|
|
38
53
|
/**
|
|
39
54
|
* Creates a test case in BrowserStack Test Management.
|
|
40
55
|
*/
|
|
41
|
-
|
|
56
|
+
async function createTestCaseTool(args) {
|
|
42
57
|
// Sanitize input arguments
|
|
43
|
-
const cleanedArgs = sanitizeArgs(args);
|
|
58
|
+
const cleanedArgs = (0, create_testcase_js_1.sanitizeArgs)(args);
|
|
44
59
|
try {
|
|
45
|
-
trackMCP("createTestCase", serverInstance.server.getClientVersion());
|
|
46
|
-
return await
|
|
60
|
+
(0, instrumentation_js_1.trackMCP)("createTestCase", serverInstance.server.getClientVersion());
|
|
61
|
+
return await (0, create_testcase_js_1.createTestCase)(cleanedArgs);
|
|
47
62
|
}
|
|
48
63
|
catch (err) {
|
|
49
|
-
|
|
50
|
-
trackMCP("createTestCase", serverInstance.server.getClientVersion(), err);
|
|
64
|
+
logger_js_1.default.error("Failed to create test case: %s", err);
|
|
65
|
+
(0, instrumentation_js_1.trackMCP)("createTestCase", serverInstance.server.getClientVersion(), err);
|
|
51
66
|
return {
|
|
52
67
|
content: [
|
|
53
68
|
{
|
|
@@ -63,13 +78,13 @@ export async function createTestCaseTool(args) {
|
|
|
63
78
|
/**
|
|
64
79
|
* Lists test cases in a project with optional filters (status, priority, custom fields, etc.)
|
|
65
80
|
*/
|
|
66
|
-
|
|
81
|
+
async function listTestCasesTool(args) {
|
|
67
82
|
try {
|
|
68
|
-
trackMCP("listTestCases", serverInstance.server.getClientVersion());
|
|
69
|
-
return await listTestCases(args);
|
|
83
|
+
(0, instrumentation_js_1.trackMCP)("listTestCases", serverInstance.server.getClientVersion());
|
|
84
|
+
return await (0, list_testcases_js_1.listTestCases)(args);
|
|
70
85
|
}
|
|
71
86
|
catch (err) {
|
|
72
|
-
trackMCP("listTestCases", serverInstance.server.getClientVersion(), err);
|
|
87
|
+
(0, instrumentation_js_1.trackMCP)("listTestCases", serverInstance.server.getClientVersion(), err);
|
|
73
88
|
return {
|
|
74
89
|
content: [
|
|
75
90
|
{
|
|
@@ -85,13 +100,13 @@ export async function listTestCasesTool(args) {
|
|
|
85
100
|
/**
|
|
86
101
|
* Creates a test run in BrowserStack Test Management.
|
|
87
102
|
*/
|
|
88
|
-
|
|
103
|
+
async function createTestRunTool(args) {
|
|
89
104
|
try {
|
|
90
|
-
trackMCP("createTestRun", serverInstance.server.getClientVersion());
|
|
91
|
-
return await createTestRun(args);
|
|
105
|
+
(0, instrumentation_js_1.trackMCP)("createTestRun", serverInstance.server.getClientVersion());
|
|
106
|
+
return await (0, create_testrun_js_1.createTestRun)(args);
|
|
92
107
|
}
|
|
93
108
|
catch (err) {
|
|
94
|
-
trackMCP("createTestRun", serverInstance.server.getClientVersion(), err);
|
|
109
|
+
(0, instrumentation_js_1.trackMCP)("createTestRun", serverInstance.server.getClientVersion(), err);
|
|
95
110
|
return {
|
|
96
111
|
content: [
|
|
97
112
|
{
|
|
@@ -107,13 +122,13 @@ export async function createTestRunTool(args) {
|
|
|
107
122
|
/**
|
|
108
123
|
* Lists test runs in a project with optional filters (date ranges, assignee, state, etc.)
|
|
109
124
|
*/
|
|
110
|
-
|
|
125
|
+
async function listTestRunsTool(args) {
|
|
111
126
|
try {
|
|
112
|
-
trackMCP("listTestRuns", serverInstance.server.getClientVersion());
|
|
113
|
-
return await listTestRuns(args);
|
|
127
|
+
(0, instrumentation_js_1.trackMCP)("listTestRuns", serverInstance.server.getClientVersion());
|
|
128
|
+
return await (0, list_testruns_js_1.listTestRuns)(args);
|
|
114
129
|
}
|
|
115
130
|
catch (err) {
|
|
116
|
-
trackMCP("listTestRuns", serverInstance.server.getClientVersion(), err);
|
|
131
|
+
(0, instrumentation_js_1.trackMCP)("listTestRuns", serverInstance.server.getClientVersion(), err);
|
|
117
132
|
return {
|
|
118
133
|
content: [
|
|
119
134
|
{
|
|
@@ -131,13 +146,13 @@ export async function listTestRunsTool(args) {
|
|
|
131
146
|
* This function allows for partial updates to an existing test run.
|
|
132
147
|
* It takes the project identifier and test run ID as parameters.
|
|
133
148
|
*/
|
|
134
|
-
|
|
149
|
+
async function updateTestRunTool(args) {
|
|
135
150
|
try {
|
|
136
|
-
trackMCP("updateTestRun", serverInstance.server.getClientVersion());
|
|
137
|
-
return await updateTestRun(args);
|
|
151
|
+
(0, instrumentation_js_1.trackMCP)("updateTestRun", serverInstance.server.getClientVersion());
|
|
152
|
+
return await (0, update_testrun_js_1.updateTestRun)(args);
|
|
138
153
|
}
|
|
139
154
|
catch (err) {
|
|
140
|
-
trackMCP("updateTestRun", serverInstance.server.getClientVersion(), err);
|
|
155
|
+
(0, instrumentation_js_1.trackMCP)("updateTestRun", serverInstance.server.getClientVersion(), err);
|
|
141
156
|
return {
|
|
142
157
|
content: [
|
|
143
158
|
{
|
|
@@ -153,13 +168,13 @@ export async function updateTestRunTool(args) {
|
|
|
153
168
|
/**
|
|
154
169
|
* Adds a test result to a specific test run via BrowserStack Test Management API.
|
|
155
170
|
*/
|
|
156
|
-
|
|
171
|
+
async function addTestResultTool(args) {
|
|
157
172
|
try {
|
|
158
|
-
trackMCP("addTestResult", serverInstance.server.getClientVersion());
|
|
159
|
-
return await addTestResult(args);
|
|
173
|
+
(0, instrumentation_js_1.trackMCP)("addTestResult", serverInstance.server.getClientVersion());
|
|
174
|
+
return await (0, add_test_result_js_1.addTestResult)(args);
|
|
160
175
|
}
|
|
161
176
|
catch (err) {
|
|
162
|
-
trackMCP("addTestResult", serverInstance.server.getClientVersion(), err);
|
|
177
|
+
(0, instrumentation_js_1.trackMCP)("addTestResult", serverInstance.server.getClientVersion(), err);
|
|
163
178
|
return {
|
|
164
179
|
content: [
|
|
165
180
|
{
|
|
@@ -175,13 +190,13 @@ export async function addTestResultTool(args) {
|
|
|
175
190
|
/**
|
|
176
191
|
* Uploads files such as PDRs or screenshots to BrowserStack Test Management and get file mapping ID back.
|
|
177
192
|
*/
|
|
178
|
-
|
|
193
|
+
async function uploadProductRequirementFileTool(args) {
|
|
179
194
|
try {
|
|
180
|
-
trackMCP("
|
|
181
|
-
return await uploadFile(args);
|
|
195
|
+
(0, instrumentation_js_1.trackMCP)("uploadProductRequirementFile", serverInstance.server.getClientVersion());
|
|
196
|
+
return await (0, upload_file_js_1.uploadFile)(args);
|
|
182
197
|
}
|
|
183
198
|
catch (err) {
|
|
184
|
-
trackMCP("
|
|
199
|
+
(0, instrumentation_js_1.trackMCP)("uploadProductRequirementFile", serverInstance.server.getClientVersion(), err);
|
|
185
200
|
return {
|
|
186
201
|
content: [
|
|
187
202
|
{
|
|
@@ -197,13 +212,13 @@ export async function uploadFileTestManagementTool(args) {
|
|
|
197
212
|
/**
|
|
198
213
|
* Creates test cases from a file in BrowserStack Test Management.
|
|
199
214
|
*/
|
|
200
|
-
|
|
215
|
+
async function createTestCasesFromFileTool(args, context) {
|
|
201
216
|
try {
|
|
202
|
-
trackMCP("createTestCasesFromFile", serverInstance.server.getClientVersion());
|
|
203
|
-
return await createTestCasesFromFile(args, context);
|
|
217
|
+
(0, instrumentation_js_1.trackMCP)("createTestCasesFromFile", serverInstance.server.getClientVersion());
|
|
218
|
+
return await (0, testcase_from_file_js_1.createTestCasesFromFile)(args, context);
|
|
204
219
|
}
|
|
205
220
|
catch (err) {
|
|
206
|
-
trackMCP("createTestCasesFromFile", serverInstance.server.getClientVersion(), err);
|
|
221
|
+
(0, instrumentation_js_1.trackMCP)("createTestCasesFromFile", serverInstance.server.getClientVersion(), err);
|
|
207
222
|
return {
|
|
208
223
|
content: [
|
|
209
224
|
{
|
|
@@ -219,15 +234,15 @@ export async function createTestCasesFromFileTool(args, context) {
|
|
|
219
234
|
/**
|
|
220
235
|
* Registers both project/folder and test-case tools.
|
|
221
236
|
*/
|
|
222
|
-
|
|
237
|
+
function addTestManagementTools(server) {
|
|
223
238
|
serverInstance = server;
|
|
224
|
-
server.tool("createProjectOrFolder", "Create a project and/or folder in BrowserStack Test Management.", CreateProjFoldSchema.shape, createProjectOrFolderTool);
|
|
225
|
-
server.tool("createTestCase", "Use this tool to create a test case in BrowserStack Test Management.", CreateTestCaseSchema.shape, createTestCaseTool);
|
|
226
|
-
server.tool("listTestCases", "List test cases in a project with optional filters (status, priority, custom fields, etc.)", ListTestCasesSchema.shape, listTestCasesTool);
|
|
227
|
-
server.tool("createTestRun", "Create a test run in BrowserStack Test Management.", CreateTestRunSchema.shape, createTestRunTool);
|
|
228
|
-
server.tool("listTestRuns", "List test runs in a project with optional filters (date ranges, assignee, state, etc.)", ListTestRunsSchema.shape, listTestRunsTool);
|
|
229
|
-
server.tool("updateTestRun", "Update a test run in BrowserStack Test Management.", UpdateTestRunSchema.shape, updateTestRunTool);
|
|
230
|
-
server.tool("addTestResult", "Add a test result to a specific test run via BrowserStack Test Management API.", AddTestResultSchema.shape, addTestResultTool);
|
|
231
|
-
server.tool("
|
|
232
|
-
server.tool("createTestCasesFromFile", "Create test cases from a file in BrowserStack Test Management.", CreateTestCasesFromFileSchema.shape, createTestCasesFromFileTool);
|
|
239
|
+
server.tool("createProjectOrFolder", "Create a project and/or folder in BrowserStack Test Management.", create_project_folder_js_1.CreateProjFoldSchema.shape, createProjectOrFolderTool);
|
|
240
|
+
server.tool("createTestCase", "Use this tool to create a test case in BrowserStack Test Management.", create_testcase_js_1.CreateTestCaseSchema.shape, createTestCaseTool);
|
|
241
|
+
server.tool("listTestCases", "List test cases in a project with optional filters (status, priority, custom fields, etc.)", list_testcases_js_1.ListTestCasesSchema.shape, listTestCasesTool);
|
|
242
|
+
server.tool("createTestRun", "Create a test run in BrowserStack Test Management.", create_testrun_js_1.CreateTestRunSchema.shape, createTestRunTool);
|
|
243
|
+
server.tool("listTestRuns", "List test runs in a project with optional filters (date ranges, assignee, state, etc.)", list_testruns_js_1.ListTestRunsSchema.shape, listTestRunsTool);
|
|
244
|
+
server.tool("updateTestRun", "Update a test run in BrowserStack Test Management.", update_testrun_js_1.UpdateTestRunSchema.shape, updateTestRunTool);
|
|
245
|
+
server.tool("addTestResult", "Add a test result to a specific test run via BrowserStack Test Management API.", add_test_result_js_1.AddTestResultSchema.shape, addTestResultTool);
|
|
246
|
+
server.tool("uploadProductRequirementFile", "Upload files such as PDRs or PDFs to BrowserStack Test Management and get file mapping ID back. Its Used for generating test cases from file.", upload_file_js_1.UploadFileSchema.shape, uploadProductRequirementFileTool);
|
|
247
|
+
server.tool("createTestCasesFromFile", "Create test cases from a file in BrowserStack Test Management.", types_js_1.CreateTestCasesFromFileSchema.shape, createTestCasesFromFileTool);
|
|
233
248
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@browserstack/mcp-server",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "BrowserStack's Official MCP Server",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -34,10 +34,11 @@
|
|
|
34
34
|
"author": "",
|
|
35
35
|
"license": "ISC",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
37
|
+
"@modelcontextprotocol/sdk": "^1.11.4",
|
|
38
38
|
"@types/form-data": "^2.5.2",
|
|
39
39
|
"axios": "^1.8.4",
|
|
40
40
|
"browserstack-local": "^1.5.6",
|
|
41
|
+
"csv-parse": "^5.6.0",
|
|
41
42
|
"dotenv": "^16.5.0",
|
|
42
43
|
"form-data": "^4.0.2",
|
|
43
44
|
"pino": "^9.6.0",
|
|
@@ -49,6 +50,7 @@
|
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
52
|
"@eslint/js": "^9.25.0",
|
|
53
|
+
"@types/csv-parse": "^1.1.12",
|
|
52
54
|
"@types/node": "^22.14.1",
|
|
53
55
|
"@types/uuid": "^10.0.0",
|
|
54
56
|
"eslint": "^9.25.0",
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import axios from "axios";
|
|
2
|
-
import config from "../../config.js";
|
|
3
|
-
import { AxiosError } from "axios";
|
|
4
|
-
export async function startAccessibilityScan(name, urlList) {
|
|
5
|
-
try {
|
|
6
|
-
const response = await axios.post("https://api-accessibility.browserstack.com/api/website-scanner/v1/scans", {
|
|
7
|
-
name,
|
|
8
|
-
urlList,
|
|
9
|
-
recurring: false,
|
|
10
|
-
}, {
|
|
11
|
-
auth: {
|
|
12
|
-
username: config.browserstackUsername,
|
|
13
|
-
password: config.browserstackAccessKey,
|
|
14
|
-
},
|
|
15
|
-
});
|
|
16
|
-
if (!response.data.success) {
|
|
17
|
-
throw new Error(`Unable to create an accessibility scan: ${response.data.errors?.join(", ")}`);
|
|
18
|
-
}
|
|
19
|
-
return response.data;
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
if (error instanceof AxiosError) {
|
|
23
|
-
if (error.response?.data?.error) {
|
|
24
|
-
throw new Error(`Failed to start accessibility scan: ${error.response?.data?.error}`);
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
throw new Error(`Failed to start accessibility scan: ${error.response?.data?.message || error.message}`);
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
throw error;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
export async function pollScanStatus(scanId, scanRunId) {
|
|
34
|
-
try {
|
|
35
|
-
const response = await axios.get(`https://api-accessibility.browserstack.com/api/website-scanner/v1/scans/${scanId}/scan_runs/${scanRunId}/status`, {
|
|
36
|
-
auth: {
|
|
37
|
-
username: config.browserstackUsername,
|
|
38
|
-
password: config.browserstackAccessKey,
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
if (!response.data.success) {
|
|
42
|
-
throw new Error(`Failed to get scan status: ${response.data.errors?.join(", ")}`);
|
|
43
|
-
}
|
|
44
|
-
return response.data.data?.status || "unknown";
|
|
45
|
-
}
|
|
46
|
-
catch (error) {
|
|
47
|
-
if (error instanceof AxiosError) {
|
|
48
|
-
throw new Error(`Failed to get scan status: ${error.response?.data?.message || error.message}`);
|
|
49
|
-
}
|
|
50
|
-
throw error;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
export async function waitUntilScanComplete(scanId, scanRunId) {
|
|
54
|
-
return new Promise((resolve, reject) => {
|
|
55
|
-
const interval = setInterval(async () => {
|
|
56
|
-
try {
|
|
57
|
-
const status = await pollScanStatus(scanId, scanRunId);
|
|
58
|
-
if (status === "completed") {
|
|
59
|
-
clearInterval(interval);
|
|
60
|
-
resolve();
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
catch (error) {
|
|
64
|
-
clearInterval(interval);
|
|
65
|
-
reject(error);
|
|
66
|
-
}
|
|
67
|
-
}, 5000); // Poll every 5 seconds
|
|
68
|
-
// Set a timeout of 5 minutes
|
|
69
|
-
setTimeout(() => {
|
|
70
|
-
clearInterval(interval);
|
|
71
|
-
reject(new Error("Scan timed out after 5 minutes"));
|
|
72
|
-
}, 5 * 60 * 1000);
|
|
73
|
-
});
|
|
74
|
-
}
|