@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.
Files changed (54) hide show
  1. package/dist/config.js +6 -2
  2. package/dist/index.js +34 -31
  3. package/dist/lib/api.js +9 -3
  4. package/dist/lib/constants.js +6 -3
  5. package/dist/lib/device-cache.js +21 -14
  6. package/dist/lib/error.js +6 -3
  7. package/dist/lib/fuzzy.js +4 -1
  8. package/dist/lib/inmemory-store.js +4 -1
  9. package/dist/lib/instrumentation.js +18 -12
  10. package/dist/lib/local.js +35 -27
  11. package/dist/lib/utils.js +15 -6
  12. package/dist/logger.js +6 -4
  13. package/dist/tools/accessibility.js +54 -18
  14. package/dist/tools/accessiblity-utils/report-fetcher.js +35 -0
  15. package/dist/tools/accessiblity-utils/report-parser.js +57 -0
  16. package/dist/tools/accessiblity-utils/scanner.js +87 -0
  17. package/dist/tools/appautomate-utils/appautomate.js +27 -17
  18. package/dist/tools/appautomate.js +35 -29
  19. package/dist/tools/applive-utils/fuzzy-search.js +6 -3
  20. package/dist/tools/applive-utils/start-session.js +20 -14
  21. package/dist/tools/applive-utils/upload-app.js +51 -12
  22. package/dist/tools/applive.js +25 -18
  23. package/dist/tools/automate-utils/fetch-screenshots.js +14 -8
  24. package/dist/tools/automate.js +21 -14
  25. package/dist/tools/bstack-sdk.js +18 -14
  26. package/dist/tools/failurelogs-utils/app-automate.js +26 -15
  27. package/dist/tools/failurelogs-utils/automate.js +23 -13
  28. package/dist/tools/getFailureLogs.js +49 -42
  29. package/dist/tools/live-utils/desktop-filter.js +11 -8
  30. package/dist/tools/live-utils/mobile-filter.js +10 -7
  31. package/dist/tools/live-utils/start-session.js +23 -17
  32. package/dist/tools/live-utils/types.js +5 -2
  33. package/dist/tools/live-utils/version-resolver.js +4 -1
  34. package/dist/tools/live.js +29 -23
  35. package/dist/tools/observability.js +19 -12
  36. package/dist/tools/sdk-utils/constants.js +9 -3
  37. package/dist/tools/sdk-utils/instructions.js +9 -4
  38. package/dist/tools/sdk-utils/types.js +2 -1
  39. package/dist/tools/testmanagement-utils/TCG-utils/api.js +38 -26
  40. package/dist/tools/testmanagement-utils/TCG-utils/config.js +10 -5
  41. package/dist/tools/testmanagement-utils/TCG-utils/helpers.js +8 -3
  42. package/dist/tools/testmanagement-utils/TCG-utils/types.js +8 -5
  43. package/dist/tools/testmanagement-utils/add-test-result.js +24 -17
  44. package/dist/tools/testmanagement-utils/create-project-folder.js +28 -21
  45. package/dist/tools/testmanagement-utils/create-testcase.js +38 -30
  46. package/dist/tools/testmanagement-utils/create-testrun.js +30 -23
  47. package/dist/tools/testmanagement-utils/list-testcases.js +22 -15
  48. package/dist/tools/testmanagement-utils/list-testruns.js +19 -12
  49. package/dist/tools/testmanagement-utils/testcase-from-file.js +22 -16
  50. package/dist/tools/testmanagement-utils/update-testrun.js +22 -15
  51. package/dist/tools/testmanagement-utils/upload-file.js +29 -22
  52. package/dist/tools/testmanagement.js +76 -61
  53. package/package.json +4 -2
  54. package/dist/tools/accessiblity-utils/accessibility.js +0 -74
@@ -1,31 +1,38 @@
1
- import { z } from "zod";
2
- import axios from "axios";
3
- import FormData from "form-data";
4
- import fs from "fs";
5
- import path from "path";
6
- import { v4 as uuidv4 } from "uuid";
7
- import config from "../../config.js";
8
- import { signedUrlMap } from "../../lib/inmemory-store.js";
9
- import { projectIdentifierToId } from "./TCG-utils/api.js";
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
- export const UploadFileSchema = z.object({
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
- export async function uploadFile(args) {
31
+ async function uploadFile(args) {
25
32
  const { project_identifier, file_path } = args;
26
33
  try {
27
34
  // Validate file exists
28
- if (!fs.existsSync(file_path)) {
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 FormData();
43
- formData.append("attachments[]", fs.createReadStream(file_path));
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 axios.post(uploadUrl, formData, {
52
+ const response = await axios_1.default.post(uploadUrl, formData, {
46
53
  headers: {
47
54
  ...formData.getHeaders(),
48
- "API-TOKEN": `${config.browserstackUsername}:${config.browserstackAccessKey}`,
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 = uuidv4();
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 ${path.basename(file_path)} to BrowserStack Test Management.`,
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
- import { trackMCP } from "../lib/instrumentation.js";
2
- import logger from "../logger.js";
3
- import { createProjectOrFolder, CreateProjFoldSchema, } from "./testmanagement-utils/create-project-folder.js";
4
- import { createTestCase as createTestCaseAPI, sanitizeArgs, CreateTestCaseSchema, } from "./testmanagement-utils/create-testcase.js";
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
- import { listTestCases, ListTestCasesSchema, } from "./testmanagement-utils/list-testcases.js";
7
- import { CreateTestRunSchema, createTestRun, } from "./testmanagement-utils/create-testrun.js";
8
- import { ListTestRunsSchema, listTestRuns, } from "./testmanagement-utils/list-testruns.js";
9
- import { UpdateTestRunSchema, updateTestRun, } from "./testmanagement-utils/update-testrun.js";
10
- import { addTestResult, AddTestResultSchema, } from "./testmanagement-utils/add-test-result.js";
11
- import { UploadFileSchema, uploadFile, } from "./testmanagement-utils/upload-file.js";
12
- import { createTestCasesFromFile } from "./testmanagement-utils/testcase-from-file.js";
13
- import { CreateTestCasesFromFileSchema } from "./testmanagement-utils/TCG-utils/types.js";
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
- export async function createProjectOrFolderTool(args) {
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
- logger.error("Failed to create project/folder: %s", err);
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
- export async function createTestCaseTool(args) {
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 createTestCaseAPI(cleanedArgs);
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
- logger.error("Failed to create test case: %s", err);
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
- export async function listTestCasesTool(args) {
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
- export async function createTestRunTool(args) {
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
- export async function listTestRunsTool(args) {
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
- export async function updateTestRunTool(args) {
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
- export async function addTestResultTool(args) {
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
- export async function uploadFileTestManagementTool(args) {
193
+ async function uploadProductRequirementFileTool(args) {
179
194
  try {
180
- trackMCP("uploadFileTestManagement", serverInstance.server.getClientVersion());
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("uploadFileTestManagement", serverInstance.server.getClientVersion(), err);
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
- export async function createTestCasesFromFileTool(args, context) {
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
- export default function addTestManagementTools(server) {
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("uploadFileTestManagement", "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.", UploadFileSchema.shape, uploadFileTestManagementTool);
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.14",
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.10.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
- }