Skip to content

Commit 0e260c6

Browse files
committed
Refactor failure log retrieval functions to return formatted strings instead of objects
1 parent f3e8b9c commit 0e260c6

File tree

3 files changed

+68
-100
lines changed

3 files changed

+68
-100
lines changed

src/tools/failurelogs-utils/app-automate.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const auth = Buffer.from(
1313
export async function retrieveDeviceLogs(
1414
sessionId: string,
1515
buildId: string,
16-
): Promise<LogResponse> {
16+
): Promise<string> {
1717
const url = `https://api.browserstack.com/app-automate/builds/${buildId}/sessions/${sessionId}/deviceLogs`;
1818

1919
const response = await fetch(url, {
@@ -23,18 +23,21 @@ export async function retrieveDeviceLogs(
2323
},
2424
});
2525

26-
const validationResult = validateLogResponse(response, "device logs");
27-
if (validationResult) return validationResult;
26+
const validationError = validateLogResponse(response, "device logs");
27+
if (validationError) return validationError.message!;
2828

2929
const logText = await response.text();
30-
return { logs: filterDeviceFailures(logText) };
30+
const logs = filterDeviceFailures(logText);
31+
return logs.length > 0
32+
? `Device Failures (${logs.length} found):\n${JSON.stringify(logs, null, 2)}`
33+
: "No device failures found";
3134
}
3235

3336
// APPIUM LOGS
3437
export async function retrieveAppiumLogs(
3538
sessionId: string,
3639
buildId: string,
37-
): Promise<LogResponse> {
40+
): Promise<string> {
3841
const url = `https://api.browserstack.com/app-automate/builds/${buildId}/sessions/${sessionId}/appiumlogs`;
3942

4043
const response = await fetch(url, {
@@ -44,18 +47,21 @@ export async function retrieveAppiumLogs(
4447
},
4548
});
4649

47-
const validationResult = validateLogResponse(response, "Appium logs");
48-
if (validationResult) return validationResult;
50+
const validationError = validateLogResponse(response, "Appium logs");
51+
if (validationError) return validationError.message!;
4952

5053
const logText = await response.text();
51-
return { logs: filterAppiumFailures(logText) };
54+
const logs = filterAppiumFailures(logText);
55+
return logs.length > 0
56+
? `Appium Failures (${logs.length} found):\n${JSON.stringify(logs, null, 2)}`
57+
: "No Appium failures found";
5258
}
5359

5460
// CRASH LOGS
5561
export async function retrieveCrashLogs(
5662
sessionId: string,
5763
buildId: string,
58-
): Promise<LogResponse> {
64+
): Promise<string> {
5965
const url = `https://api.browserstack.com/app-automate/builds/${buildId}/sessions/${sessionId}/crashlogs`;
6066

6167
const response = await fetch(url, {
@@ -65,11 +71,14 @@ export async function retrieveCrashLogs(
6571
},
6672
});
6773

68-
const validationResult = validateLogResponse(response, "crash logs");
69-
if (validationResult) return validationResult;
74+
const validationError = validateLogResponse(response, "crash logs");
75+
if (validationError) return validationError.message!;
7076

7177
const logText = await response.text();
72-
return { logs: filterCrashFailures(logText) };
78+
const logs = filterCrashFailures(logText);
79+
return logs.length > 0
80+
? `Crash Failures (${logs.length} found):\n${JSON.stringify(logs, null, 2)}`
81+
: "No crash failures found";
7382
}
7483

7584
// FILTER HELPERS

src/tools/failurelogs-utils/automate.ts

Lines changed: 39 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import {
44
HarFile,
55
filterLinesByKeywords,
66
validateLogResponse,
7-
LogResponse,
87
} from "./utils.js";
98

109
const auth = Buffer.from(
@@ -14,7 +13,7 @@ const auth = Buffer.from(
1413
// NETWORK LOGS
1514
export async function retrieveNetworkFailures(
1615
sessionId: string,
17-
): Promise<LogResponse> {
16+
): Promise<string> {
1817
const url = `https://api.browserstack.com/automate/sessions/${sessionId}/networklogs`;
1918

2019
const response = await fetch(url, {
@@ -25,45 +24,40 @@ export async function retrieveNetworkFailures(
2524
},
2625
});
2726

28-
const validationResult = validateLogResponse(response, "network logs");
29-
if (validationResult) return validationResult;
27+
const validationError = validateLogResponse(response, "network logs");
28+
if (validationError) return validationError.message!;
3029

3130
const networklogs: HarFile = await response.json();
32-
33-
// Filter for failure logs
3431
const failureEntries: HarEntry[] = networklogs.log.entries.filter(
35-
(entry: HarEntry) => {
36-
return (
37-
entry.response.status === 0 ||
38-
entry.response.status >= 400 ||
39-
entry.response._error !== undefined
40-
);
41-
},
32+
(entry: HarEntry) =>
33+
entry.response.status === 0 ||
34+
entry.response.status >= 400 ||
35+
entry.response._error !== undefined
4236
);
43-
44-
return {
45-
logs: failureEntries.map((entry: any) => ({
46-
startedDateTime: entry.startedDateTime,
47-
request: {
48-
method: entry.request?.method,
49-
url: entry.request?.url,
50-
queryString: entry.request?.queryString,
51-
},
52-
response: {
53-
status: entry.response?.status,
54-
statusText: entry.response?.statusText,
55-
_error: entry.response?._error,
56-
},
57-
serverIPAddress: entry.serverIPAddress,
58-
time: entry.time,
59-
})),
60-
};
37+
38+
return failureEntries.length > 0
39+
? `Network Failures (${failureEntries.length} found):\n${JSON.stringify(failureEntries.map((entry: any) => ({
40+
startedDateTime: entry.startedDateTime,
41+
request: {
42+
method: entry.request?.method,
43+
url: entry.request?.url,
44+
queryString: entry.request?.queryString,
45+
},
46+
response: {
47+
status: entry.response?.status,
48+
statusText: entry.response?.statusText,
49+
_error: entry.response?._error,
50+
},
51+
serverIPAddress: entry.serverIPAddress,
52+
time: entry.time,
53+
})), null, 2)}`
54+
: "No network failures found";
6155
}
6256

6357
// SESSION LOGS
6458
export async function retrieveSessionFailures(
6559
sessionId: string,
66-
): Promise<LogResponse> {
60+
): Promise<string> {
6761
const url = `https://api.browserstack.com/automate/sessions/${sessionId}/logs`;
6862

6963
const response = await fetch(url, {
@@ -73,17 +67,20 @@ export async function retrieveSessionFailures(
7367
},
7468
});
7569

76-
const validationResult = validateLogResponse(response, "session logs");
77-
if (validationResult) return validationResult;
70+
const validationError = validateLogResponse(response, "session logs");
71+
if (validationError) return validationError.message!;
7872

7973
const logText = await response.text();
80-
return { logs: filterSessionFailures(logText) };
74+
const logs = filterSessionFailures(logText);
75+
return logs.length > 0
76+
? `Session Failures (${logs.length} found):\n${JSON.stringify(logs, null, 2)}`
77+
: "No session failures found";
8178
}
8279

8380
// CONSOLE LOGS
8481
export async function retrieveConsoleFailures(
8582
sessionId: string,
86-
): Promise<LogResponse> {
83+
): Promise<string> {
8784
const url = `https://api.browserstack.com/automate/sessions/${sessionId}/consolelogs`;
8885

8986
const response = await fetch(url, {
@@ -93,11 +90,14 @@ export async function retrieveConsoleFailures(
9390
},
9491
});
9592

96-
const validationResult = validateLogResponse(response, "console logs");
97-
if (validationResult) return validationResult;
93+
const validationError = validateLogResponse(response, "console logs");
94+
if (validationError) return validationError.message!;
9895

9996
const logText = await response.text();
100-
return { logs: filterConsoleFailures(logText) };
97+
const logs = filterConsoleFailures(logText);
98+
return logs.length > 0
99+
? `Console Failures (${logs.length} found):\n${JSON.stringify(logs, null, 2)}`
100+
: "No console failures found";
101101
}
102102

103103
// FILTER: session logs

src/tools/getFailureLogs.ts

Lines changed: 8 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
22
import { z } from "zod";
33
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
44
import logger from "../logger.js";
5+
import { trackMCP } from "../lib/instrumentation.js";
56

67
import {
78
retrieveNetworkFailures,
@@ -14,7 +15,7 @@ import {
1415
retrieveAppiumLogs,
1516
retrieveCrashLogs,
1617
} from "./failurelogs-utils/app-automate.js";
17-
import { trackMCP } from "../lib/instrumentation.js";
18+
1819
import {
1920
AppAutomateLogType,
2021
AutomateLogType,
@@ -97,79 +98,37 @@ export async function getFailureLogs(args: {
9798
switch (logType) {
9899
case AutomateLogType.NetworkLogs: {
99100
response = await retrieveNetworkFailures(args.sessionId);
100-
results.push({
101-
type: "text",
102-
text:
103-
response.message ||
104-
(response.logs && response.logs.length > 0
105-
? `Network Failures (${response.logs.length} found):\n${JSON.stringify(response.logs, null, 2)}`
106-
: "No network failures found"),
107-
});
101+
results.push({ type: "text", text: response });
108102
break;
109103
}
110104

111105
case AutomateLogType.SessionLogs: {
112106
response = await retrieveSessionFailures(args.sessionId);
113-
results.push({
114-
type: "text",
115-
text:
116-
response.message ||
117-
(response.logs && response.logs.length > 0
118-
? `Session Failures (${response.logs.length} found):\n${JSON.stringify(response.logs, null, 2)}`
119-
: "No session failures found"),
120-
});
107+
results.push({ type: "text", text: response });
121108
break;
122109
}
123110

124111
case AutomateLogType.ConsoleLogs: {
125112
response = await retrieveConsoleFailures(args.sessionId);
126-
results.push({
127-
type: "text",
128-
text:
129-
response.message ||
130-
(response.logs && response.logs.length > 0
131-
? `Console Failures (${response.logs.length} found):\n${JSON.stringify(response.logs, null, 2)}`
132-
: "No console failures found"),
133-
});
113+
results.push({ type: "text", text: response });
134114
break;
135115
}
136116

137117
case AppAutomateLogType.DeviceLogs: {
138118
response = await retrieveDeviceLogs(args.sessionId, args.buildId!);
139-
results.push({
140-
type: "text",
141-
text:
142-
response.message ||
143-
(response.logs && response.logs.length > 0
144-
? `Device Failures (${response.logs.length} found):\n${JSON.stringify(response.logs, null, 2)}`
145-
: "No device failures found"),
146-
});
119+
results.push({ type: "text", text: response });
147120
break;
148121
}
149122

150123
case AppAutomateLogType.AppiumLogs: {
151124
response = await retrieveAppiumLogs(args.sessionId, args.buildId!);
152-
results.push({
153-
type: "text",
154-
text:
155-
response.message ||
156-
(response.logs && response.logs.length > 0
157-
? `Appium Failures (${response.logs.length} found):\n${JSON.stringify(response.logs, null, 2)}`
158-
: "No Appium failures found"),
159-
});
125+
results.push({ type: "text", text: response });
160126
break;
161127
}
162128

163129
case AppAutomateLogType.CrashLogs: {
164130
response = await retrieveCrashLogs(args.sessionId, args.buildId!);
165-
results.push({
166-
type: "text",
167-
text:
168-
response.message ||
169-
(response.logs && response.logs.length > 0
170-
? `Crash Failures (${response.logs.length} found):\n${JSON.stringify(response.logs, null, 2)}`
171-
: "No crash failures found"),
172-
});
131+
results.push({ type: "text", text: response });
173132
break;
174133
}
175134
}

0 commit comments

Comments
 (0)