@browserstack/mcp-server 1.1.8 → 1.2.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.
Files changed (125) hide show
  1. package/README.md +71 -35
  2. package/dist/config.d.ts +13 -0
  3. package/dist/config.js +10 -6
  4. package/dist/index.d.ts +4 -0
  5. package/dist/index.js +20 -30
  6. package/dist/lib/api.d.ts +2 -0
  7. package/dist/lib/api.js +10 -5
  8. package/dist/lib/apiClient.d.ts +31 -0
  9. package/dist/lib/apiClient.js +108 -0
  10. package/dist/lib/constants.d.ts +17 -0
  11. package/dist/lib/device-cache.d.ts +9 -0
  12. package/dist/lib/device-cache.js +3 -3
  13. package/dist/lib/error.d.ts +7 -0
  14. package/dist/lib/fuzzy.d.ts +1 -0
  15. package/dist/lib/get-auth.d.ts +2 -0
  16. package/dist/lib/get-auth.js +8 -0
  17. package/dist/lib/inmemory-store.d.ts +1 -0
  18. package/dist/lib/instrumentation.d.ts +4 -0
  19. package/dist/lib/instrumentation.js +8 -7
  20. package/dist/lib/local.d.ts +3 -0
  21. package/dist/lib/local.js +12 -3
  22. package/dist/lib/types.d.ts +4 -0
  23. package/dist/lib/types.js +1 -0
  24. package/dist/lib/utils.d.ts +4 -0
  25. package/dist/lib/version-resolver.d.ts +6 -0
  26. package/dist/logger.d.ts +3 -0
  27. package/dist/logger.js +20 -4
  28. package/dist/oninitialized.d.ts +2 -0
  29. package/dist/oninitialized.js +2 -7
  30. package/dist/server-factory.d.ts +3 -0
  31. package/dist/server-factory.js +37 -0
  32. package/dist/tools/accessibility.d.ts +3 -0
  33. package/dist/tools/accessibility.js +17 -10
  34. package/dist/tools/accessiblity-utils/accessibility-rag.d.ts +12 -0
  35. package/dist/tools/accessiblity-utils/accessibility-rag.js +22 -12
  36. package/dist/tools/accessiblity-utils/report-fetcher.d.ts +8 -0
  37. package/dist/tools/accessiblity-utils/report-fetcher.js +26 -16
  38. package/dist/tools/accessiblity-utils/report-parser.d.ts +23 -0
  39. package/dist/tools/accessiblity-utils/report-parser.js +3 -3
  40. package/dist/tools/accessiblity-utils/scanner.d.ts +25 -0
  41. package/dist/tools/accessiblity-utils/scanner.js +46 -24
  42. package/dist/tools/appautomate-utils/appautomate.d.ts +42 -0
  43. package/dist/tools/appautomate-utils/appautomate.js +95 -9
  44. package/dist/tools/appautomate-utils/types.d.ts +5 -0
  45. package/dist/tools/appautomate-utils/types.js +6 -0
  46. package/dist/tools/appautomate.d.ts +3 -0
  47. package/dist/tools/appautomate.js +109 -13
  48. package/dist/tools/applive-utils/device-search.d.ts +6 -0
  49. package/dist/tools/applive-utils/start-session.d.ts +15 -0
  50. package/dist/tools/applive-utils/start-session.js +11 -4
  51. package/dist/tools/applive-utils/types.d.ts +7 -0
  52. package/dist/tools/applive-utils/upload-app.d.ts +5 -0
  53. package/dist/tools/applive-utils/upload-app.js +8 -12
  54. package/dist/tools/applive-utils/version-utils.d.ts +4 -0
  55. package/dist/tools/applive.d.ts +13 -0
  56. package/dist/tools/applive.js +6 -6
  57. package/dist/tools/automate-utils/fetch-screenshots.d.ts +6 -0
  58. package/dist/tools/automate-utils/fetch-screenshots.js +16 -12
  59. package/dist/tools/automate.d.ts +9 -0
  60. package/dist/tools/automate.js +6 -6
  61. package/dist/tools/bstack-sdk.d.ts +17 -0
  62. package/dist/tools/bstack-sdk.js +47 -20
  63. package/dist/tools/failurelogs-utils/app-automate.d.ts +7 -0
  64. package/dist/tools/failurelogs-utils/app-automate.js +29 -11
  65. package/dist/tools/failurelogs-utils/automate.d.ts +6 -0
  66. package/dist/tools/failurelogs-utils/automate.js +27 -12
  67. package/dist/tools/failurelogs-utils/utils.d.ts +30 -0
  68. package/dist/tools/getFailureLogs.d.ts +14 -0
  69. package/dist/tools/getFailureLogs.js +11 -11
  70. package/dist/tools/live-utils/desktop-filter.d.ts +2 -0
  71. package/dist/tools/live-utils/mobile-filter.d.ts +2 -0
  72. package/dist/tools/live-utils/start-session.d.ts +6 -0
  73. package/dist/tools/live-utils/start-session.js +18 -5
  74. package/dist/tools/live-utils/types.d.ts +33 -0
  75. package/dist/tools/live.d.ts +3 -0
  76. package/dist/tools/live.js +11 -11
  77. package/dist/tools/observability.d.ts +5 -0
  78. package/dist/tools/observability.js +14 -11
  79. package/dist/tools/sdk-utils/commands.d.ts +3 -0
  80. package/dist/tools/sdk-utils/commands.js +20 -5
  81. package/dist/tools/sdk-utils/constants.d.ts +2 -0
  82. package/dist/tools/sdk-utils/constants.js +284 -160
  83. package/dist/tools/sdk-utils/instructions.d.ts +6 -0
  84. package/dist/tools/sdk-utils/instructions.js +28 -6
  85. package/dist/tools/sdk-utils/percy/constants.d.ts +3 -0
  86. package/dist/tools/sdk-utils/percy/constants.js +36 -25
  87. package/dist/tools/sdk-utils/percy/instructions.d.ts +10 -0
  88. package/dist/tools/sdk-utils/percy/types.d.ts +5 -0
  89. package/dist/tools/sdk-utils/types.d.ts +39 -0
  90. package/dist/tools/sdk-utils/types.js +3 -0
  91. package/dist/tools/selfheal-utils/selfheal.d.ts +11 -0
  92. package/dist/tools/selfheal-utils/selfheal.js +10 -6
  93. package/dist/tools/selfheal.d.ts +7 -0
  94. package/dist/tools/selfheal.js +6 -6
  95. package/dist/tools/testmanagement-utils/TCG-utils/api.d.ts +34 -0
  96. package/dist/tools/testmanagement-utils/TCG-utils/api.js +57 -44
  97. package/dist/tools/testmanagement-utils/TCG-utils/config.d.ts +5 -0
  98. package/dist/tools/testmanagement-utils/TCG-utils/helpers.d.ts +13 -0
  99. package/dist/tools/testmanagement-utils/TCG-utils/helpers.js +2 -1
  100. package/dist/tools/testmanagement-utils/TCG-utils/types.d.ts +26 -0
  101. package/dist/tools/testmanagement-utils/add-test-result.d.ts +42 -0
  102. package/dist/tools/testmanagement-utils/add-test-result.js +23 -10
  103. package/dist/tools/testmanagement-utils/create-lca-steps.d.ts +100 -0
  104. package/dist/tools/testmanagement-utils/create-lca-steps.js +64 -55
  105. package/dist/tools/testmanagement-utils/create-project-folder.d.ts +31 -0
  106. package/dist/tools/testmanagement-utils/create-project-folder.js +31 -21
  107. package/dist/tools/testmanagement-utils/create-testcase.d.ts +122 -0
  108. package/dist/tools/testmanagement-utils/create-testcase.js +13 -10
  109. package/dist/tools/testmanagement-utils/create-testrun.d.ts +82 -0
  110. package/dist/tools/testmanagement-utils/create-testrun.js +11 -8
  111. package/dist/tools/testmanagement-utils/list-testcases.d.ts +30 -0
  112. package/dist/tools/testmanagement-utils/list-testcases.js +9 -7
  113. package/dist/tools/testmanagement-utils/list-testruns.d.ts +22 -0
  114. package/dist/tools/testmanagement-utils/list-testruns.js +9 -7
  115. package/dist/tools/testmanagement-utils/poll-lca-status.d.ts +11 -0
  116. package/dist/tools/testmanagement-utils/poll-lca-status.js +12 -8
  117. package/dist/tools/testmanagement-utils/testcase-from-file.d.ts +4 -0
  118. package/dist/tools/testmanagement-utils/testcase-from-file.js +6 -6
  119. package/dist/tools/testmanagement-utils/update-testrun.d.ts +40 -0
  120. package/dist/tools/testmanagement-utils/update-testrun.js +11 -7
  121. package/dist/tools/testmanagement-utils/upload-file.d.ts +20 -0
  122. package/dist/tools/testmanagement-utils/upload-file.js +8 -6
  123. package/dist/tools/testmanagement.d.ts +60 -0
  124. package/dist/tools/testmanagement.js +51 -53
  125. package/package.json +1 -1
@@ -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 axios from "axios";
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 response = await axios.post(url, { test_run: args.test_run }, {
59
- auth: {
60
- username: config.browserstackUsername,
61
- password: config.browserstackAccessKey,
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
- headers: { "Content-Type": "application/json" },
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 axios from "axios";
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 resp = await axios.get(url, {
43
- auth: {
44
- username: config.browserstackUsername,
45
- password: config.browserstackAccessKey,
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 axios from "axios";
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 resp = await axios.get(url, {
28
- auth: {
29
- username: config.browserstackUsername,
30
- password: config.browserstackAccessKey,
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 axios from "axios";
2
- import config from "../../config.js";
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 response = await axios.get(url, {
53
+ const authString = getBrowserStackAuth(config);
54
+ const response = await apiClient.get({
55
+ url,
53
56
  headers: {
54
- "API-TOKEN": `${config.browserstackUsername}:${config.browserstackAccessKey}`,
57
+ "API-TOKEN": authString,
55
58
  accept: "application/json, text/plain, */*",
56
59
  },
57
60
  });
58
- if (response.data.data.success && response.data.data.test_case) {
59
- const testCase = response.data.data.test_case;
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
- response.data.data.metadata?.lcnc_build_map;
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 {
@@ -0,0 +1,40 @@
1
+ import { z } from "zod";
2
+ import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3
+ import { BrowserStackConfig } from "../../lib/types.js";
4
+ /**
5
+ * Schema for updating a test run with partial fields.
6
+ */
7
+ export declare const UpdateTestRunSchema: z.ZodObject<{
8
+ project_identifier: z.ZodString;
9
+ test_run_id: z.ZodString;
10
+ test_run: z.ZodObject<{
11
+ name: z.ZodOptional<z.ZodString>;
12
+ run_state: z.ZodOptional<z.ZodEnum<["new_run", "in_progress", "under_review", "rejected", "done", "closed"]>>;
13
+ }, "strip", z.ZodTypeAny, {
14
+ name?: string | undefined;
15
+ run_state?: "new_run" | "in_progress" | "under_review" | "rejected" | "done" | "closed" | undefined;
16
+ }, {
17
+ name?: string | undefined;
18
+ run_state?: "new_run" | "in_progress" | "under_review" | "rejected" | "done" | "closed" | undefined;
19
+ }>;
20
+ }, "strip", z.ZodTypeAny, {
21
+ project_identifier: string;
22
+ test_run: {
23
+ name?: string | undefined;
24
+ run_state?: "new_run" | "in_progress" | "under_review" | "rejected" | "done" | "closed" | undefined;
25
+ };
26
+ test_run_id: string;
27
+ }, {
28
+ project_identifier: string;
29
+ test_run: {
30
+ name?: string | undefined;
31
+ run_state?: "new_run" | "in_progress" | "under_review" | "rejected" | "done" | "closed" | undefined;
32
+ };
33
+ test_run_id: string;
34
+ }>;
35
+ type UpdateTestRunArgs = z.infer<typeof UpdateTestRunSchema>;
36
+ /**
37
+ * Partially updates an existing test run.
38
+ */
39
+ export declare function updateTestRun(args: UpdateTestRunArgs, config: BrowserStackConfig): Promise<CallToolResult>;
40
+ export {};
@@ -1,5 +1,5 @@
1
- import axios from "axios";
2
- import config from "../../config.js";
1
+ import { apiClient } from "../../lib/apiClient.js";
2
+ import { getBrowserStackAuth } from "../../lib/get-auth.js";
3
3
  import { z } from "zod";
4
4
  import { formatAxiosError } from "../../lib/error.js";
5
5
  /**
@@ -28,15 +28,19 @@ export const UpdateTestRunSchema = z.object({
28
28
  /**
29
29
  * Partially updates an existing test run.
30
30
  */
31
- export async function updateTestRun(args) {
31
+ export async function updateTestRun(args, config) {
32
32
  try {
33
33
  const body = { test_run: args.test_run };
34
34
  const url = `https://test-management.browserstack.com/api/v2/projects/${encodeURIComponent(args.project_identifier)}/test-runs/${encodeURIComponent(args.test_run_id)}/update`;
35
- const resp = await axios.patch(url, body, {
36
- auth: {
37
- username: config.browserstackUsername,
38
- password: config.browserstackAccessKey,
35
+ const authString = getBrowserStackAuth(config);
36
+ const [username, password] = authString.split(":");
37
+ const resp = await apiClient.patch({
38
+ url,
39
+ headers: {
40
+ Authorization: "Basic " + Buffer.from(`${username}:${password}`).toString("base64"),
41
+ "Content-Type": "application/json",
39
42
  },
43
+ body,
40
44
  });
41
45
  const data = resp.data;
42
46
  if (!data.success) {
@@ -0,0 +1,20 @@
1
+ import { z } from "zod";
2
+ import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
3
+ import { BrowserStackConfig } from "../../lib/types.js";
4
+ /**
5
+ * Schema for the upload file tool
6
+ */
7
+ export declare const UploadFileSchema: z.ZodObject<{
8
+ project_identifier: z.ZodString;
9
+ file_path: z.ZodString;
10
+ }, "strip", z.ZodTypeAny, {
11
+ project_identifier: string;
12
+ file_path: string;
13
+ }, {
14
+ project_identifier: string;
15
+ file_path: string;
16
+ }>;
17
+ /**
18
+ * Uploads a file to BrowserStack Test Management and returns the signed URL.
19
+ */
20
+ export declare function uploadFile(args: z.infer<typeof UploadFileSchema>, config: BrowserStackConfig): Promise<CallToolResult>;
@@ -1,10 +1,10 @@
1
1
  import { z } from "zod";
2
- import axios from "axios";
2
+ import { apiClient } from "../../lib/apiClient.js";
3
3
  import FormData from "form-data";
4
4
  import fs from "fs";
5
5
  import path from "path";
6
6
  import { v4 as uuidv4 } from "uuid";
7
- import config from "../../config.js";
7
+ import { getBrowserStackAuth } from "../../lib/get-auth.js";
8
8
  import { signedUrlMap } from "../../lib/inmemory-store.js";
9
9
  import { projectIdentifierToId } from "./TCG-utils/api.js";
10
10
  /**
@@ -21,7 +21,7 @@ export const UploadFileSchema = z.object({
21
21
  /**
22
22
  * Uploads a file to BrowserStack Test Management and returns the signed URL.
23
23
  */
24
- export async function uploadFile(args) {
24
+ export async function uploadFile(args, config) {
25
25
  const { project_identifier, file_path } = args;
26
26
  try {
27
27
  // Validate file exists
@@ -38,16 +38,18 @@ export async function uploadFile(args) {
38
38
  };
39
39
  }
40
40
  // Get the project ID
41
- const projectIdResponse = await projectIdentifierToId(project_identifier);
41
+ const projectIdResponse = await projectIdentifierToId(project_identifier, config);
42
42
  const formData = new FormData();
43
43
  formData.append("attachments[]", fs.createReadStream(file_path));
44
44
  const uploadUrl = `https://test-management.browserstack.com/api/v1/projects/${projectIdResponse}/generic/attachments/ai_uploads`;
45
- const response = await axios.post(uploadUrl, formData, {
45
+ const response = await apiClient.post({
46
+ url: uploadUrl,
46
47
  headers: {
47
48
  ...formData.getHeaders(),
48
- "API-TOKEN": `${config.browserstackUsername}:${config.browserstackAccessKey}`,
49
+ "API-TOKEN": getBrowserStackAuth(config),
49
50
  accept: "application/json, text/plain, */*",
50
51
  },
52
+ body: formData,
51
53
  });
52
54
  if (response.status >= 200 &&
53
55
  response.status < 300 &&
@@ -0,0 +1,60 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { z } from "zod";
3
+ import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
4
+ import { CreateProjFoldSchema } from "./testmanagement-utils/create-project-folder.js";
5
+ import { TestCaseCreateRequest } from "./testmanagement-utils/create-testcase.js";
6
+ import { ListTestCasesSchema } from "./testmanagement-utils/list-testcases.js";
7
+ import { CreateTestRunSchema } from "./testmanagement-utils/create-testrun.js";
8
+ import { ListTestRunsSchema } from "./testmanagement-utils/list-testruns.js";
9
+ import { UpdateTestRunSchema } from "./testmanagement-utils/update-testrun.js";
10
+ import { AddTestResultSchema } from "./testmanagement-utils/add-test-result.js";
11
+ import { UploadFileSchema } from "./testmanagement-utils/upload-file.js";
12
+ import { CreateTestCasesFromFileSchema } from "./testmanagement-utils/TCG-utils/types.js";
13
+ import { CreateLCAStepsSchema } from "./testmanagement-utils/create-lca-steps.js";
14
+ import { BrowserStackConfig } from "../lib/types.js";
15
+ /**
16
+ * Wrapper to call createProjectOrFolder util.
17
+ */
18
+ export declare function createProjectOrFolderTool(args: z.infer<typeof CreateProjFoldSchema>, config: BrowserStackConfig, server: McpServer): Promise<CallToolResult>;
19
+ /**
20
+ * Creates a test case in BrowserStack Test Management.
21
+ */
22
+ export declare function createTestCaseTool(args: TestCaseCreateRequest, config: BrowserStackConfig, server: McpServer): Promise<CallToolResult>;
23
+ /**
24
+ * Lists test cases in a project with optional filters (status, priority, custom fields, etc.)
25
+ */
26
+ export declare function listTestCasesTool(args: z.infer<typeof ListTestCasesSchema>, config: BrowserStackConfig, server: McpServer): Promise<CallToolResult>;
27
+ /**
28
+ * Creates a test run in BrowserStack Test Management.
29
+ */
30
+ export declare function createTestRunTool(args: z.infer<typeof CreateTestRunSchema>, config: BrowserStackConfig, server: McpServer): Promise<CallToolResult>;
31
+ /**
32
+ * Lists test runs in a project with optional filters (date ranges, assignee, state, etc.)
33
+ */
34
+ export declare function listTestRunsTool(args: z.infer<typeof ListTestRunsSchema>, config: BrowserStackConfig, server: McpServer): Promise<CallToolResult>;
35
+ /**
36
+ * Updates a test run in BrowserStack Test Management.
37
+ * This function allows for partial updates to an existing test run.
38
+ * It takes the project identifier and test run ID as parameters.
39
+ */
40
+ export declare function updateTestRunTool(args: z.infer<typeof UpdateTestRunSchema>, config: BrowserStackConfig, server: McpServer): Promise<CallToolResult>;
41
+ /**
42
+ * Adds a test result to a specific test run via BrowserStack Test Management API.
43
+ */
44
+ export declare function addTestResultTool(args: z.infer<typeof AddTestResultSchema>, config: BrowserStackConfig, server: McpServer): Promise<CallToolResult>;
45
+ /**
46
+ * Uploads files such as PDRs or screenshots to BrowserStack Test Management and get file mapping ID back.
47
+ */
48
+ export declare function uploadProductRequirementFileTool(args: z.infer<typeof UploadFileSchema>, config: BrowserStackConfig, server: McpServer): Promise<CallToolResult>;
49
+ /**
50
+ * Creates test cases from a file in BrowserStack Test Management.
51
+ */
52
+ export declare function createTestCasesFromFileTool(args: z.infer<typeof CreateTestCasesFromFileSchema>, context: any, config: BrowserStackConfig, server: McpServer): Promise<CallToolResult>;
53
+ /**
54
+ * Creates LCA (Low Code Automation) steps for a test case in BrowserStack Test Management.
55
+ */
56
+ export declare function createLCAStepsTool(args: z.infer<typeof CreateLCAStepsSchema>, context: any, config: BrowserStackConfig, server: McpServer): Promise<CallToolResult>;
57
+ /**
58
+ * Registers both project/folder and test-case tools.
59
+ */
60
+ export default function addTestManagementTools(server: McpServer, config: BrowserStackConfig): void;