@browserstack/mcp-server 1.0.13 → 1.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/dist/config.js +2 -6
- package/dist/index.js +29 -32
- package/dist/lib/api.js +3 -57
- package/dist/lib/constants.js +14 -0
- package/dist/lib/device-cache.js +32 -33
- package/dist/lib/error.js +3 -6
- package/dist/lib/fuzzy.js +1 -4
- package/dist/lib/inmemory-store.js +1 -0
- package/dist/lib/instrumentation.js +12 -18
- package/dist/lib/local.js +27 -35
- package/dist/lib/utils.js +29 -4
- package/dist/logger.js +4 -9
- package/dist/tools/accessibility.js +51 -21
- package/dist/tools/accessiblity-utils/report-fetcher.js +28 -0
- package/dist/tools/accessiblity-utils/report-parser.js +51 -0
- package/dist/tools/accessiblity-utils/scanner.js +80 -0
- package/dist/tools/appautomate-utils/appautomate.js +95 -0
- package/dist/tools/appautomate.js +116 -0
- package/dist/tools/applive-utils/fuzzy-search.js +3 -6
- package/dist/tools/applive-utils/start-session.js +14 -20
- package/dist/tools/applive-utils/upload-app.js +12 -51
- package/dist/tools/applive.js +18 -25
- package/dist/tools/automate-utils/fetch-screenshots.js +59 -0
- package/dist/tools/automate.js +44 -37
- package/dist/tools/bstack-sdk.js +14 -18
- package/dist/tools/failurelogs-utils/app-automate.js +88 -0
- package/dist/tools/failurelogs-utils/automate.js +97 -0
- package/dist/tools/getFailureLogs.js +173 -0
- package/dist/tools/live-utils/desktop-filter.js +8 -11
- package/dist/tools/live-utils/mobile-filter.js +7 -10
- package/dist/tools/live-utils/start-session.js +17 -23
- package/dist/tools/live-utils/types.js +2 -5
- package/dist/tools/live-utils/version-resolver.js +1 -4
- package/dist/tools/live.js +23 -29
- package/dist/tools/observability.js +12 -19
- package/dist/tools/sdk-utils/constants.js +3 -9
- package/dist/tools/sdk-utils/instructions.js +4 -9
- package/dist/tools/sdk-utils/types.js +1 -2
- package/dist/tools/testmanagement-utils/TCG-utils/api.js +259 -0
- package/dist/tools/testmanagement-utils/TCG-utils/config.js +5 -0
- package/dist/tools/testmanagement-utils/TCG-utils/helpers.js +53 -0
- package/dist/tools/testmanagement-utils/TCG-utils/types.js +8 -0
- package/dist/tools/testmanagement-utils/add-test-result.js +18 -25
- package/dist/tools/testmanagement-utils/create-project-folder.js +21 -28
- package/dist/tools/testmanagement-utils/create-testcase.js +30 -38
- package/dist/tools/testmanagement-utils/create-testrun.js +23 -30
- package/dist/tools/testmanagement-utils/list-testcases.js +16 -23
- package/dist/tools/testmanagement-utils/list-testruns.js +13 -20
- package/dist/tools/testmanagement-utils/testcase-from-file.js +42 -0
- package/dist/tools/testmanagement-utils/update-testrun.js +16 -23
- package/dist/tools/testmanagement-utils/upload-file.js +101 -0
- package/dist/tools/testmanagement.js +98 -61
- package/package.json +13 -7
- package/dist/tools/accessiblity-utils/accessibility.js +0 -82
|
@@ -1,37 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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.default = addTestManagementTools;
|
|
14
|
-
const instrumentation_1 = require("../lib/instrumentation");
|
|
15
|
-
const logger_1 = __importDefault(require("../logger"));
|
|
16
|
-
const create_project_folder_1 = require("./testmanagement-utils/create-project-folder");
|
|
17
|
-
const create_testcase_1 = require("./testmanagement-utils/create-testcase");
|
|
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";
|
|
18
5
|
let serverInstance;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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";
|
|
14
|
+
//TODO: Moving the traceMCP and catch block to the parent(server) function
|
|
24
15
|
/**
|
|
25
16
|
* Wrapper to call createProjectOrFolder util.
|
|
26
17
|
*/
|
|
27
|
-
async function createProjectOrFolderTool(args) {
|
|
18
|
+
export async function createProjectOrFolderTool(args) {
|
|
28
19
|
try {
|
|
29
|
-
|
|
30
|
-
return await
|
|
20
|
+
trackMCP("createProjectOrFolder", serverInstance.server.getClientVersion());
|
|
21
|
+
return await createProjectOrFolder(args);
|
|
31
22
|
}
|
|
32
23
|
catch (err) {
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
logger.error("Failed to create project/folder: %s", err);
|
|
25
|
+
trackMCP("createProjectOrFolder", serverInstance.server.getClientVersion(), err);
|
|
35
26
|
return {
|
|
36
27
|
content: [
|
|
37
28
|
{
|
|
@@ -47,16 +38,16 @@ async function createProjectOrFolderTool(args) {
|
|
|
47
38
|
/**
|
|
48
39
|
* Creates a test case in BrowserStack Test Management.
|
|
49
40
|
*/
|
|
50
|
-
async function createTestCaseTool(args) {
|
|
41
|
+
export async function createTestCaseTool(args) {
|
|
51
42
|
// Sanitize input arguments
|
|
52
|
-
const cleanedArgs =
|
|
43
|
+
const cleanedArgs = sanitizeArgs(args);
|
|
53
44
|
try {
|
|
54
|
-
|
|
55
|
-
return await (
|
|
45
|
+
trackMCP("createTestCase", serverInstance.server.getClientVersion());
|
|
46
|
+
return await createTestCaseAPI(cleanedArgs);
|
|
56
47
|
}
|
|
57
48
|
catch (err) {
|
|
58
|
-
|
|
59
|
-
|
|
49
|
+
logger.error("Failed to create test case: %s", err);
|
|
50
|
+
trackMCP("createTestCase", serverInstance.server.getClientVersion(), err);
|
|
60
51
|
return {
|
|
61
52
|
content: [
|
|
62
53
|
{
|
|
@@ -72,13 +63,13 @@ async function createTestCaseTool(args) {
|
|
|
72
63
|
/**
|
|
73
64
|
* Lists test cases in a project with optional filters (status, priority, custom fields, etc.)
|
|
74
65
|
*/
|
|
75
|
-
async function listTestCasesTool(args) {
|
|
66
|
+
export async function listTestCasesTool(args) {
|
|
76
67
|
try {
|
|
77
|
-
|
|
78
|
-
return await
|
|
68
|
+
trackMCP("listTestCases", serverInstance.server.getClientVersion());
|
|
69
|
+
return await listTestCases(args);
|
|
79
70
|
}
|
|
80
71
|
catch (err) {
|
|
81
|
-
|
|
72
|
+
trackMCP("listTestCases", serverInstance.server.getClientVersion(), err);
|
|
82
73
|
return {
|
|
83
74
|
content: [
|
|
84
75
|
{
|
|
@@ -94,13 +85,13 @@ async function listTestCasesTool(args) {
|
|
|
94
85
|
/**
|
|
95
86
|
* Creates a test run in BrowserStack Test Management.
|
|
96
87
|
*/
|
|
97
|
-
async function createTestRunTool(args) {
|
|
88
|
+
export async function createTestRunTool(args) {
|
|
98
89
|
try {
|
|
99
|
-
|
|
100
|
-
return await
|
|
90
|
+
trackMCP("createTestRun", serverInstance.server.getClientVersion());
|
|
91
|
+
return await createTestRun(args);
|
|
101
92
|
}
|
|
102
93
|
catch (err) {
|
|
103
|
-
|
|
94
|
+
trackMCP("createTestRun", serverInstance.server.getClientVersion(), err);
|
|
104
95
|
return {
|
|
105
96
|
content: [
|
|
106
97
|
{
|
|
@@ -116,13 +107,13 @@ async function createTestRunTool(args) {
|
|
|
116
107
|
/**
|
|
117
108
|
* Lists test runs in a project with optional filters (date ranges, assignee, state, etc.)
|
|
118
109
|
*/
|
|
119
|
-
async function listTestRunsTool(args) {
|
|
110
|
+
export async function listTestRunsTool(args) {
|
|
120
111
|
try {
|
|
121
|
-
|
|
122
|
-
return await
|
|
112
|
+
trackMCP("listTestRuns", serverInstance.server.getClientVersion());
|
|
113
|
+
return await listTestRuns(args);
|
|
123
114
|
}
|
|
124
115
|
catch (err) {
|
|
125
|
-
|
|
116
|
+
trackMCP("listTestRuns", serverInstance.server.getClientVersion(), err);
|
|
126
117
|
return {
|
|
127
118
|
content: [
|
|
128
119
|
{
|
|
@@ -140,13 +131,13 @@ async function listTestRunsTool(args) {
|
|
|
140
131
|
* This function allows for partial updates to an existing test run.
|
|
141
132
|
* It takes the project identifier and test run ID as parameters.
|
|
142
133
|
*/
|
|
143
|
-
async function updateTestRunTool(args) {
|
|
134
|
+
export async function updateTestRunTool(args) {
|
|
144
135
|
try {
|
|
145
|
-
|
|
146
|
-
return await
|
|
136
|
+
trackMCP("updateTestRun", serverInstance.server.getClientVersion());
|
|
137
|
+
return await updateTestRun(args);
|
|
147
138
|
}
|
|
148
139
|
catch (err) {
|
|
149
|
-
|
|
140
|
+
trackMCP("updateTestRun", serverInstance.server.getClientVersion(), err);
|
|
150
141
|
return {
|
|
151
142
|
content: [
|
|
152
143
|
{
|
|
@@ -162,13 +153,13 @@ async function updateTestRunTool(args) {
|
|
|
162
153
|
/**
|
|
163
154
|
* Adds a test result to a specific test run via BrowserStack Test Management API.
|
|
164
155
|
*/
|
|
165
|
-
async function addTestResultTool(args) {
|
|
156
|
+
export async function addTestResultTool(args) {
|
|
166
157
|
try {
|
|
167
|
-
|
|
168
|
-
return await
|
|
158
|
+
trackMCP("addTestResult", serverInstance.server.getClientVersion());
|
|
159
|
+
return await addTestResult(args);
|
|
169
160
|
}
|
|
170
161
|
catch (err) {
|
|
171
|
-
|
|
162
|
+
trackMCP("addTestResult", serverInstance.server.getClientVersion(), err);
|
|
172
163
|
return {
|
|
173
164
|
content: [
|
|
174
165
|
{
|
|
@@ -181,16 +172,62 @@ async function addTestResultTool(args) {
|
|
|
181
172
|
};
|
|
182
173
|
}
|
|
183
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Uploads files such as PDRs or screenshots to BrowserStack Test Management and get file mapping ID back.
|
|
177
|
+
*/
|
|
178
|
+
export async function uploadProductRequirementFileTool(args) {
|
|
179
|
+
try {
|
|
180
|
+
trackMCP("uploadProductRequirementFile", serverInstance.server.getClientVersion());
|
|
181
|
+
return await uploadFile(args);
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
trackMCP("uploadProductRequirementFile", serverInstance.server.getClientVersion(), err);
|
|
185
|
+
return {
|
|
186
|
+
content: [
|
|
187
|
+
{
|
|
188
|
+
type: "text",
|
|
189
|
+
text: `Failed to upload file: ${err instanceof Error ? err.message : "Unknown error"}. Please open an issue on GitHub if the problem persists`,
|
|
190
|
+
isError: true,
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
isError: true,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Creates test cases from a file in BrowserStack Test Management.
|
|
199
|
+
*/
|
|
200
|
+
export async function createTestCasesFromFileTool(args, context) {
|
|
201
|
+
try {
|
|
202
|
+
trackMCP("createTestCasesFromFile", serverInstance.server.getClientVersion());
|
|
203
|
+
return await createTestCasesFromFile(args, context);
|
|
204
|
+
}
|
|
205
|
+
catch (err) {
|
|
206
|
+
trackMCP("createTestCasesFromFile", serverInstance.server.getClientVersion(), err);
|
|
207
|
+
return {
|
|
208
|
+
content: [
|
|
209
|
+
{
|
|
210
|
+
type: "text",
|
|
211
|
+
text: `Failed to create test cases from file: ${err instanceof Error ? err.message : "Unknown error"}. Please open an issue on GitHub if the problem persists`,
|
|
212
|
+
isError: true,
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
isError: true,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
}
|
|
184
219
|
/**
|
|
185
220
|
* Registers both project/folder and test-case tools.
|
|
186
221
|
*/
|
|
187
|
-
function addTestManagementTools(server) {
|
|
222
|
+
export default function addTestManagementTools(server) {
|
|
188
223
|
serverInstance = server;
|
|
189
|
-
server.tool("createProjectOrFolder", "Create a project and/or folder in BrowserStack Test Management.",
|
|
190
|
-
server.tool("createTestCase", "Use this tool to create a test case in BrowserStack Test Management.",
|
|
191
|
-
server.tool("listTestCases", "List test cases in a project with optional filters (status, priority, custom fields, etc.)",
|
|
192
|
-
server.tool("createTestRun", "Create a test run in BrowserStack Test Management.",
|
|
193
|
-
server.tool("listTestRuns", "List test runs in a project with optional filters (date ranges, assignee, state, etc.)",
|
|
194
|
-
server.tool("updateTestRun", "Update a test run in BrowserStack Test Management.",
|
|
195
|
-
server.tool("addTestResult", "Add a test result to a specific test run via BrowserStack Test Management API.",
|
|
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("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.", UploadFileSchema.shape, uploadProductRequirementFileTool);
|
|
232
|
+
server.tool("createTestCasesFromFile", "Create test cases from a file in BrowserStack Test Management.", CreateTestCasesFromFileSchema.shape, createTestCasesFromFileTool);
|
|
196
233
|
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@browserstack/mcp-server",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
4
4
|
"description": "BrowserStack's Official MCP Server",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/browserstack/mcp-server.git"
|
|
9
9
|
},
|
|
10
|
+
"type": "module",
|
|
10
11
|
"scripts": {
|
|
11
12
|
"build": "npm run lint && npm run format && npm test && tsc",
|
|
12
13
|
"start": "node dist/index.js",
|
|
13
14
|
"dev": "tsx watch --clear-screen=false src/index.ts",
|
|
14
|
-
"test": "
|
|
15
|
+
"test": "vitest run",
|
|
15
16
|
"lint": "eslint . --ext .ts",
|
|
16
17
|
"format": "prettier --write \"src/**/*.ts\""
|
|
17
18
|
},
|
|
@@ -33,26 +34,31 @@
|
|
|
33
34
|
"author": "",
|
|
34
35
|
"license": "ISC",
|
|
35
36
|
"dependencies": {
|
|
36
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
37
|
+
"@modelcontextprotocol/sdk": "^1.11.4",
|
|
37
38
|
"@types/form-data": "^2.5.2",
|
|
38
39
|
"axios": "^1.8.4",
|
|
39
40
|
"browserstack-local": "^1.5.6",
|
|
41
|
+
"csv-parse": "^5.6.0",
|
|
40
42
|
"dotenv": "^16.5.0",
|
|
41
43
|
"form-data": "^4.0.2",
|
|
42
44
|
"pino": "^9.6.0",
|
|
43
45
|
"pino-pretty": "^13.0.0",
|
|
46
|
+
"sharp": "^0.34.1",
|
|
47
|
+
"uuid": "^11.1.0",
|
|
48
|
+
"webdriverio": "^9.13.0",
|
|
44
49
|
"zod": "^3.24.3"
|
|
45
50
|
},
|
|
46
51
|
"devDependencies": {
|
|
47
52
|
"@eslint/js": "^9.25.0",
|
|
48
|
-
"@types/
|
|
53
|
+
"@types/csv-parse": "^1.1.12",
|
|
49
54
|
"@types/node": "^22.14.1",
|
|
55
|
+
"@types/uuid": "^10.0.0",
|
|
50
56
|
"eslint": "^9.25.0",
|
|
51
|
-
"jest": "^29.7.0",
|
|
52
57
|
"prettier": "^3.5.3",
|
|
53
|
-
"ts-jest": "^29.3.2",
|
|
54
58
|
"tsx": "^4.19.3",
|
|
55
59
|
"typescript": "^5.8.3",
|
|
56
|
-
"typescript-eslint": "^8.30.1"
|
|
60
|
+
"typescript-eslint": "^8.30.1",
|
|
61
|
+
"vite": "^6.3.5",
|
|
62
|
+
"vitest": "^3.1.3"
|
|
57
63
|
}
|
|
58
64
|
}
|
|
@@ -1,82 +0,0 @@
|
|
|
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.startAccessibilityScan = startAccessibilityScan;
|
|
7
|
-
exports.pollScanStatus = pollScanStatus;
|
|
8
|
-
exports.waitUntilScanComplete = waitUntilScanComplete;
|
|
9
|
-
const axios_1 = __importDefault(require("axios"));
|
|
10
|
-
const config_js_1 = __importDefault(require("../../config.js"));
|
|
11
|
-
const axios_2 = require("axios");
|
|
12
|
-
async function startAccessibilityScan(name, urlList) {
|
|
13
|
-
try {
|
|
14
|
-
const response = await axios_1.default.post("https://api-accessibility.browserstack.com/api/website-scanner/v1/scans", {
|
|
15
|
-
name,
|
|
16
|
-
urlList,
|
|
17
|
-
recurring: false,
|
|
18
|
-
}, {
|
|
19
|
-
auth: {
|
|
20
|
-
username: config_js_1.default.browserstackUsername,
|
|
21
|
-
password: config_js_1.default.browserstackAccessKey,
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
if (!response.data.success) {
|
|
25
|
-
throw new Error(`Unable to create an accessibility scan: ${response.data.errors?.join(", ")}`);
|
|
26
|
-
}
|
|
27
|
-
return response.data;
|
|
28
|
-
}
|
|
29
|
-
catch (error) {
|
|
30
|
-
if (error instanceof axios_2.AxiosError) {
|
|
31
|
-
if (error.response?.data?.error) {
|
|
32
|
-
throw new Error(`Failed to start accessibility scan: ${error.response?.data?.error}`);
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
throw new Error(`Failed to start accessibility scan: ${error.response?.data?.message || error.message}`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
throw error;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
async function pollScanStatus(scanId, scanRunId) {
|
|
42
|
-
try {
|
|
43
|
-
const response = await axios_1.default.get(`https://api-accessibility.browserstack.com/api/website-scanner/v1/scans/${scanId}/scan_runs/${scanRunId}/status`, {
|
|
44
|
-
auth: {
|
|
45
|
-
username: config_js_1.default.browserstackUsername,
|
|
46
|
-
password: config_js_1.default.browserstackAccessKey,
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
if (!response.data.success) {
|
|
50
|
-
throw new Error(`Failed to get scan status: ${response.data.errors?.join(", ")}`);
|
|
51
|
-
}
|
|
52
|
-
return response.data.data?.status || "unknown";
|
|
53
|
-
}
|
|
54
|
-
catch (error) {
|
|
55
|
-
if (error instanceof axios_2.AxiosError) {
|
|
56
|
-
throw new Error(`Failed to get scan status: ${error.response?.data?.message || error.message}`);
|
|
57
|
-
}
|
|
58
|
-
throw error;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
async function waitUntilScanComplete(scanId, scanRunId) {
|
|
62
|
-
return new Promise((resolve, reject) => {
|
|
63
|
-
const interval = setInterval(async () => {
|
|
64
|
-
try {
|
|
65
|
-
const status = await pollScanStatus(scanId, scanRunId);
|
|
66
|
-
if (status === "completed") {
|
|
67
|
-
clearInterval(interval);
|
|
68
|
-
resolve();
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
catch (error) {
|
|
72
|
-
clearInterval(interval);
|
|
73
|
-
reject(error);
|
|
74
|
-
}
|
|
75
|
-
}, 5000); // Poll every 5 seconds
|
|
76
|
-
// Set a timeout of 5 minutes
|
|
77
|
-
setTimeout(() => {
|
|
78
|
-
clearInterval(interval);
|
|
79
|
-
reject(new Error("Scan timed out after 5 minutes"));
|
|
80
|
-
}, 5 * 60 * 1000);
|
|
81
|
-
});
|
|
82
|
-
}
|